Too Fast, Too Fourier: FFT Code Golf


48

Implementa la Trasformata di Fourier veloce nel minor numero possibile di personaggi.

Regole:

  • Vince la soluzione più breve
  • Si può presumere che l'ingresso sia un array 1D la cui lunghezza è una potenza di due.
  • Puoi usare l'algoritmo che preferisci, ma la soluzione deve in realtà essere una trasformata di Fourier veloce, non solo una ingenua trasformata di Fourier discreta (ovvero deve avere un costo di calcolo asintotico di )O(NlogN)

Modificare:

  • il codice dovrebbe implementare la Fast Fourier Transform standard diretta, la cui forma può essere vista nell'equazione (3) di questo articolo di Wolfram ,

    inserisci qui la descrizione dell'immagine

  • L'utilizzo di una funzione FFT da una libreria standard preesistente o un pacchetto statistico non è consentito. La sfida qui è implementare in modo succinto l'algoritmo FFT stesso.

3
Questo è sotto specificato. Per lo meno, è necessario definire i fattori di normalizzazione e si dovrebbe anche essere consapevoli del fatto che qualsiasi ambiguità verrà intenzionalmente male interpretata. Ad esempio, "Implement" è soddisfatto della risposta " FFT(3 caratteri): è nella libreria standard"? Anche alcuni casi di test andrebbero bene.
Peter Taylor,

Importa l'ordine degli elementi di output, ovvero dobbiamo implementare la riordinazione dei bit invertiti o possiamo lasciare l'output in ordine criptato?
Paolo R

Vedi le modifiche alle regole. L'output dovrebbe essere un elenco / array con valori ordinati in base agli indici nell'espressione DFT standard, di cui sopra.
jakevdp,

2
Puoi pubblicare alcuni input e output di esempio in modo da poter testare le nostre implementazioni?
FUZxxl

2
Il titolo avrebbe dovuto essere "Fast and Fourier-s" (Fast and Furious).
clismique,

Risposte:


12

Mathematica, 95 byte

Un'altra implementazione del Cooley – Tukey FFT con l'aiuto di @ chyaong .

{n=Length@#}~With~If[n>1,Join[+##,#-#2]&[#0@#[[;;;;2]],#0@#[[2;;;;2]]I^Array[-4#/n&,n/2,0]],#]&

Ungolfed

FFT[x_] := With[{N = Length[x]},
  If[N > 1,
    With[{a = FFT[ x[[1 ;; N ;; 2]] ], 
          b = FFT[ x[[2 ;; N ;; 2]] ] * Table[E^(-2*I*Pi*k/N), {k, 0, N/2 - 1}]},
      Join[a + b, a - b]],
    x]]

1
Penso #[[;;;;2]]==#[[1;;N;;2]]e [[2;;;;2]]==[[2;;N;;2]].
chyanog,

1
101 caratteri :With[{L=Length@#},If[L>1,Join[+##,#-#2]&[#0@#[[;;;;2]],#0@#[[2;;;;2]]E^(-2I*Pi(Range[L/2]-1)/L)],#]]&
chyanog

Bene, puoi condensare un'altra funzione anonima al suo interno senza essere in conflitto con quella ricorsiva. Ho anche imparato che la parte riempie gli indici mancanti. Possiamo andare oltre utilizzando Unicode.
miglia

9

J, 37 byte

_2&(0((+,-)]%_1^i.@#%#)&$:/@|:]\)~1<#

Un miglioramento dopo pochi anni. Utilizza ancora l'algoritmo Cooley-Tukey FFT.

Salvato 4 byte usando e πi = -1, grazie a @ Leaky Nun .

Provalo online!

uso

   f =: _2&(0((+,-)]%_1^i.@#%#)&$:/@|:]\)~1<#
   f 1 1 1 1
4 0 0 0
   f 1 2 3 4
10 _2j2 _2 _2j_2
   f 5.24626 3.90746 3.72335 5.74429 4.7983 8.34171 4.46785 0.760139
36.9894 _6.21186j0.355661 1.85336j_5.74474 7.10778j_1.13334 _0.517839 7.10778j1.13334 1.85336j5.74474 _6.21186j_0.355661

Spiegazione

_2&(0((+,-)]%_1^i.@#%#)&$:/@|:]\)~1<#  Input: array A
                                    #  Length
                                  1<   Greater than one?
_2&(                            )~     Execute this if true, else return A
_2                            ]\         Get non-overlapping sublists of size 2
    0                       |:           Move axis 0 to the end, equivalent to transpose
                          /@             Reduce [even-indexed, odd-indexed]
                       &$:               Call recursively on each 
                   #                     Get the length of the odd list
                i.@                      Range from 0 to that length exclusive
                    %#                   Divide each by the odd length
             _1^                         Compute (-1)^x for each x
           ]                             Get the odd list
            %                            Divide each in that by the previous
       +                                 Add the even values and modified odd values
         -                               Subtract the even values and modified odd values
        ,                                Join the two lists and return

1

9

Python, 166 151 150 caratteri

Questo utilizza l'algoritmo radix-2 Cooley-Tukey FFT

from math import*
def F(x):N=len(x);t=N<2or(F(x[::2]),F(x[1::2]));return N<2and x or[
a+s*b/e**(2j*pi*n/N)for s in[1,-1]for(n,a,b)in zip(range(N),*t)]

Test del risultato

>>> import numpy as np
>>> x = np.random.random(512)
>>> np.allclose(F(x), np.fft.fft(x))
True

1
2 cose: in genere è meglio usare from x import*ed sum(([x for x in y] for y in z),[])è più lungo di [x for y in z for x in y].
stand

1
Grazie - questo salva 15 caratteri! 11 in più ed è un tweet.
jakevdp,

Oh, questo è sicuramente possibile. Spesso quando trovi un miglioramento, uno vecchio diventa un ostacolo.
stand,

5

Python 3: 140 134 113 caratteri

Versione corta - corta e dolce, si inserisce in un tweet (grazie a miglia ):

from math import*
def f(v):
 n=len(v)
 if n<2:return v
 a,b=f(v[::2])*2,f(v[1::2])*2;return[a[i]+b[i]/1j**(i*4/n)for i in range(n)]

(In Python 2, /sta troncando la divisione quando entrambi i lati sono numeri interi. Quindi sostituiamo (i*4/n)con (i*4.0/n), che porta la lunghezza a 115 caratteri.)

Versione lunga - maggiore chiarezza all'interno del classico Cooley-Tukey FFT:

import cmath
def transform_radix2(vector):
    n = len(vector)
    if n <= 1:  # Base case
        return vector
    elif n % 2 != 0:
        raise ValueError("Length is not a power of 2")
    else:
        k = n // 2
        even = transform_radix2(vector[0 : : 2])
        odd  = transform_radix2(vector[1 : : 2])
        return [even[i % k] + odd[i % k] * cmath.exp(i * -2j * cmath.pi / n) for i in range(n)]

1
Ridotto a 113 byte usandoe^(-2j * pi * i / n) = (-1)^(2 * i / n) = (1j)^(4 * i / n)
miglia

@miles Osservazione davvero impressionante, grazie! Dopo aver ripetutamente implementato DFT per oltre un decennio, sono diventato ossessionato da sin / cos / exp e ho dimenticato che si possono usare semplici poteri di me. Ho modificato la mia risposta per incorporare le nuove intuizioni e accreditarti.
Nayuki,

5

R: 142 133 99 95 byte

Grazie a @Giuseppe per avermi aiutato a radere 32 36 byte!

f=function(x,n=sum(x|1),y=1:(n/2)*2)`if`(n>1,f(x[-y])+c(b<-f(x[y]),-b)*exp(-2i*(y/2-1)*pi/n),x)

Un ulteriore trucco qui è usare gli argomenti predefiniti della funzione principale per creare un'istanza di alcune variabili.
L'utilizzo è sempre lo stesso:

x = c(1,1,1,1)
f(x)
[1] 4+0i 0+0i 0+0i 0+0i

Versione di 4 anni a 133 byte:

f=function(x){n=length(x);if(n>1){a=Recall(x[seq(1,n,2)]);b=Recall(x[seq(2,n,2)]);t=exp(-2i*(1:(n/2)-1)*pi/n);c(a+b*t,a-b*t)}else{x}}

Con rientri:

f=function(x){
    n=length(x)
    if(n>1){
        a=Recall(x[seq(1,n,2)])
        b=Recall(x[seq(2,n,2)])
        t=exp(-2i*(1:(n/2)-1)*pi/n)
        c(a+b*t,a-b*t)
        }else{x}
    }

Utilizza anche l'algoritmo Cooley-Tukey. Gli unici trucchi qui sono l'uso della funzione Recallche consente la ricorsività e l'uso della vettorializzazione R che accorcia notevolmente il calcolo effettivo.

Uso:

x = c(1,1,1,1)
f(x)
[1] 4+0i 0+0i 0+0i 0+0i

1
Quattro anni dopo, arriviamo a 101 byte . Non sono sicuro al 100% del motivo per cui hai già utilizzato Recallin quanto funzione già denominata, ma ehi, è facile giocare a golf con il senno di poi! :) +1, molto carino.
Giuseppe,

Sì, Recallora non è necessario, anzi. L'ho notato qualche mese fa ma ero troppo pigro per cambiarlo :) Lo modificherò.
plannapus,

Molto bella! Ho spremuto altri 4 byte! , mettendolo alla pari con Mathematica.
Giuseppe,

Grazie! Ho pensato di metterlo ylì ma non ho notato che potrebbe essere utilizzato anche per la exp(...)parte.
plannapus,

4

Python, 134

Questo prende in prestito pesantemente dalla soluzione di jakevdp, quindi l'ho impostato su un wiki della comunità.

from math import*
F=lambda x:x*(len(x)<2)or[a+s*b/e**(2j*pi*n/len(x))for s in(1,-1)for n,(a,b)in
enumerate(zip(F(x[::2]),F(x[1::2])))]

I cambiamenti:

-12 caratteri: uccidi t.

def F(x):N=len(x);t=N<2or(F(x[::2]),F(x[1::2]));return ... in zip(range(N),*t)]
def F(x):N=len(x);return ... in zip(range(N),F(x[::2]),F(x[1::2]))]

-1 carattere: esponente esponente, x*y**-z == x/y**z (questo potrebbe aiutare alcuni altri)

...[a+s*b*e**(-2j*pi*n/N)...
...[a+s*b/e**(2j*pi*n/N)...

-2 caratteri: sostituisci andcon*

...return N<2and x or[
...return x*(N<2)or[

+1 carattere: lambdaize, uccisioneN

def F(x):N=len(x);return x*(N<2)or[a+s*b/e**(2j*pi*n/N) ... zip(range(N) ...
F=lambda x:x*(len(x)<2)or[a+s*b/e**(2j*pi*n/len(x)) ... zip(range(len(x)) ...

-2 caratteri: utilizzare enumerateinvece dizip(range(len(

...for(n,a,b)in zip(range(len(x)),F(x[::2]),F(x[1::2]))]
...for n,(a,b)in enumerate(zip(F(x[::2]),F(x[1::2])))]

Penso che questa non sia più una rapida trasformata di Fourier, però ... "uccidendo" hai aggiunto alcuni calcoli non necessari che la spostano da O [N log (N)] a O [N ^ 2]
jakevdp

Sembra che non posso sottovalutare il mio post. Hai ragione, ho scambiato l'ordine del loop e ho ucciso la performance. Lascerò questo per ora, nel caso in cui trovo un modo per risolverlo.
stand

101 byte conf=lambda x:x*(len(x)<2)or[u+v/1j**(4*i/len(x))for i,(u,v)in enumerate(zip(f(x[::2])*2,f(x[1::2])*2))]
miglia

È possibile sostituire for s in(1,-1)forcon for s in 1,-1foro anche, se l'ordine non importa, for s in-1,1for.
Jonathan Frech,

4

C, 259

typedef double complex cplx;
void fft(cplx buf[],cplx out[],int n,int step){
if(step < n){
fft(out, buf,n, step * 2);
fft(out+step,buf+step,n,step*2);
for(int i=0;i<n;i+=2*step){
cplx t=cexp(-I*M_PI*i/n)*out[i+step];
buf[i/2]=out[i]+t;
buf[(i+n)/2]=out[i]-t;
}}}

Il problema è che tali implementazioni sono inutili e l'algoritmo semplice è MOLTO più veloce.


2
Puoi rimuovere un po 'di spazio in più per ottenere una quantità inferiore di caratteri, ad esempio step < npossono essere cambiati in step<ne step * 2possono essere cambiati in step*2.
Programma FOX

2
tutte le variabili, le funzioni e i typedef dovrebbero avere nomi di una lettera per salvare molti caratteri

2
Qualcuno ha suggerito un sacco di miglioramenti per questo. Dai un'occhiata qui: codegolf.stackexchange.com/review/suggested-edits/17119
Justin

1
Puoi rimuovere tutte le newline, le newline sono inutili in C
TuxCrafting il

@ TùxCräftîñg Non tutte le newline sono inutili. Sono necessari per direttive come #include, #define, #if, ecc.
Nayuki,

3

Matlab, 128 118 107 102 101 94 93 93 byte

EDIT6: grazie @algmyr per un altro byte!

function Y=f(Y);
n=numel(Y);
k=2:2:n;
if k;
   c=f(Y(k-1));
   d=f(Y(k)).*i.^(2*(2-k)/n);
   Y=[c+d;c-d];
end

EDIT5: Sempre più breve :) grazie a @sanchises

function Y=f(Y)
n=numel(Y);
k=2:2:n;
if k;
   c=f(Y(k-1));
   d=f(Y(k)).*(-1).^((2-k)/n);
   Y=[c+d;c-d];
end

EDIT4: Yay, -1 carattere in più (potrebbe anche aver fatto senza k):

function Y=f(Y)
n=numel(Y);
if n>1;
   k=2:2:n;
   c=f(Y(k-1));
   d=f(Y(k)).*(-1).^((k/2-1)*2/n)';
   Y=[c+d;c-d];
end

EDIT2 / 3: Grazie per @sanchise per ulteriori miglioramenti!

function Y=f(Y)
n=numel(Y);  
if n>1;
   c=f(Y(1:2:n));
   d=f(Y(2:2:n)).*(-1).^(-(0:n/2-1)*2/n).';
   Y=[c+d;c-d]; 
end

EDIT: potrebbe apportare alcuni miglioramenti e ho notato che la costante di ridimensionamento non è richiesta.

Questa è la versione estesa, il conteggio dei caratteri è valido se si rimuovono le nuove righe / spazi. (Funziona solo per i vettori di colonna.)

function y=f(Y)
n=numel(Y);  
y=Y;
if n>1;
   c=f(Y(1:2:n));
   d=f(Y(2:2:n));
   n=n/2;
   d=d.*exp(-pi*i*(0:n-1)/n).';
   y=[c+d;c-d]; 
end

Suggerimento: è possibile combinare le due d=linee in una sola: m=n/2;d=f(Y(2:2:n)).*exp(-pi*i*(0:m-1)/m).';. Inoltre, pensare di cambiare y=f(Y)a Y=f(Y)e rimuovere la linea 3 (e prometto che farò mai al di fuori del codice-golf)
Sanchises

Oh, grazie! Ha function Y = f(Y)qualche svantaggio diverso dalla illeggibilità?
flawr

Bene, MATLAB non si lamenterà mai di un valore di ritorno, anche se Y non viene mai modificato. È leggermente più veloce, quindi suppongo che non sia poi così male per alcuni scopi (cioè una funzione che non cambia quasi mai la variabile di input)
Sanchises

Ora, per radersi di più: m=n/2potrebbe essere rimosso e invece msostituito da n/2e n*2rispettivamente. E poi, credo fermamente, il programma è breve come potrebbe essere in MATLAB.
Sanchises,

1
E poi, credo fermamente, il programma è breve come potrebbe essere in MATLAB. - Sanchises 8 marzo 15 alle 21:05 Famose ultime parole ...
Sanchises

2

Gelatina, 31 30 28 26 byte , non competitiva

LḶ÷$N-*×,N$+ḷF
s2Z߀ç/µ¹Ṗ?

Jelly è stata creata dopo questa sfida, quindi non è competitiva.

Questo utilizza l'algoritmo ricorsivo Cooley-Tukey radix-2. Per una versione senza golf, vedi la mia risposta in Mathematica.

Provalo online o Verifica più casi di test .

Spiegazione

LḶ÷$N-*×,N$+ḷF  Helper link. Input: lists A and B
L               Get the length of A
   $            Operate on that length
 Ḷ                Make a range [0, 1, ..., length-1]
  ÷               Divide each by length
    N           Negate each
     -          The constant -1
      *         Compute -1^(x) for each x in that range
       ×        Multiply elementwise between that range and B, call it B'  
          $     Operate on that B'
         N        Negate each
        ,         Make a list [B', -B']
            ḷ   Get A
           +    Add vectorized, [B', -B'] + A = [A+B', A-B']
             F  Flatten that and return

s2Z߀ç/µ¹Ṗ?  Main link. Input: list X
         Ṗ   Curtail - Make a copy of X with the last value removed
          ?  If that list is truthy (empty lists are falsey)
       µ       Parse to the left as a monad
s2             Split X into sublists of length 2
  Z            Transpose them to get [even-index, odd-index]
   ߀          Call the main link recursively on each sublist
     ç/        Call the helper link as a dyad on the sublists and return
             Else
        ¹      Identity function on X and return

2

C (gcc) , 188 186 184 183 byte

#define d(a,b,c)f(a,b,c,1,0)
f(a,b,c,n,k)_Complex*a,*b;{_Complex z[c];*b=*a;if(n<c)for(f(a,z,c,n*2),f(a+n,z+n,c,n*2);k<c;k+=n*2)b[k+c>>1]=z[k]*2-(b[k/2]=z[k]+z[k+n]/cpow(1i,2.*k/c));}

Provalo online!

Leggermente meno golf

#define d(a,b,c)f(a,b,c,1,0)
f(a,b,c,n,k)_Complex*a,*b;{
  _Complex z[c];
  *b=*a;
  if(n<c)
    for(f(a,z,c,n*2),f(a+n,z+n,c,n*2);k<c;k+=n*2)
      b[k+c>>1]=z[k]*2-(b[k/2]=z[k]+z[k+n]/cpow(1i,2.*k/c));
}

1

Pari / GP, 76 caratteri

X(v)=my(t=-2*Pi*I/#v,s);vector(#v,k,s=t*(k-1);sum(n=0,#v-1,v[n+1]*exp(s*n)))

uso

X([1,1,1,1])
%2 = [4.000000000000000000000000000, 0.E-27 + 0.E-28*I, 0.E-28 + 0.E-27*I, 0.E-27 + 0.E-28*I]

3
Non è questo l'ingenuo DFT? (ie theta (N ^ 2))
miglia

1

Ottava , 109 103 101 100 byte

f(f=@(f)@(x,n=rows(x)){@(d=f(f)(x(k=2:2:n)).*i.^((k*2-4)/n)')[d+(c=f(f)(x(k-1)));c-d],x}{1+(n<2)}())

Provalo online!

Ooooo i miei occhi sanguinano da questa lambda maledetta ricorsiva . Gran parte di questo è stato sollevato dalla risposta di @ flawr.

f(                                          % lambda function
  f=@(f)                                    % defined in its own argument list, 
                                            % accepts itself as parameter (for recursion)
    @(x,n=rows(x)){                         % calls another lambda,
                                            % 2nd parameter is just to define a variable
      @(d=f(f)(x(k=2:2:n)).*i.^((k*2-4)/n)')% 1/4 of FFT (argument just defines a variable)
        [d+(c=f(f)(x(k-1)));                % 2/4 of FFT
         c-d                                % 4/4 of FFT
        ],                                  % This is in a @()[] to inhibit evaluation
                                            % unless actually called
      x                                     % FFT of length 1
    }{1+(n<2)}                              % if len(x)==1, return x
                                            % else return [d+c;c-d]
  ()                                        % this is probably important too
)

Non capisco cosa hai fatto ma mi piace molto.
flawr

1

APL (NARS), 58 caratteri, 116 byte

{1≥k←≢⍵:⍵⋄(∇⍵[y∼⍨⍳k])(+,-)(∇⍵[y←2×⍳t])×0J1*t÷⍨2-2×⍳t←⌊k÷2}

test

  f←{1≥k←≢⍵:⍵⋄(∇⍵[y∼⍨⍳k])(+,-)(∇⍵[y←2×⍳t])×0J1*t÷⍨2-2×⍳t←⌊k÷2}
  f 1 1 1 1
4J0 0J0 0J0 0J0 
  f 1 2 3 4
10J0 ¯2J2 ¯2J0 ¯2J¯2 
  f 1J1 2 ¯2J1  9
10J2 3J7 ¯12J2 3J¯7 
  f 5.24626,3.90746,3.72335,5.74429,4.7983,8.34171,4.46785,0.760139
36.989359J0 ¯6.211855215J0.3556612739 1.85336J¯5.744741 7.107775215J¯1.133338726 ¯0.517839J0 
  7.107775215J1.133338726 1.85336J5.744741 ¯6.211855215J¯0.3556612739 

0

Assioma, 259 , 193 , 181 , 179 byte

L(g,n,f)==>[g for i in 1..n|f]
h(a)==(n:=#a;n=1=>a;c:=h(L(a.i,n,odd? i));d:=h(L(a.i,n,even? i));n:=n/2;t:=1>0;v:=L(d.i*%i^(-2*(i-1)/n),n,t);append(L(c.i+v.i,n,t),L(c.i-v.i,n,t)))

Anche se h (a) potrebbe passare tutto il test e sarebbe ok come voce per questa 'competizione' si deve chiamare h () o hlp () attraverso fft () di seguito, per controllare gli argomenti . Non so se questo software possa essere ok perché avevo visto solo ciò che altri hanno scritto e ho cercato il modo in cui poteva funzionare in Axiom per restituire qualche possibile risultato giusto. Di seguito il codice ungolfed con alcuni commenti:

-- L(g,n,f)==>[g for i in 1..n|f]
-- this macro L, build one List from other list, where in g, there is the generic element of index i
-- (as a.i, or a.i*b.i or a.i*4), n build 1..n that is the range of i, f is the condition 
-- for insert the element in the list result.

hlp(a)==
    n:=#a;n=1=>a
    -- L(a.i,n,odd? i)  it means build a list getting "even indices i of a.i as starting from index 0" [so even is odd and odd is even]
    -- L(a.i,n,even? i) it means build a list getting "odd  indices i of a.i as starting from index 0"
    c:=hlp(L(a.i,n,odd? i));d:=hlp(L(a.i,n,even? i))
    n:=n/2;t:=1>0
    v:=L(d.i*%i^(-2*(i-1)/n),n,t)
    append(L(c.i+v.i,n,t),L(c.i-v.i,n,t))

-- Return Fast Fourier transform of list a, in the case #a=2^n
fft(a)==(n:=#a;n=0 or gcd(n,2^30)~=n=>[];hlp(a))

(5) -> h([1,1,1,1])
   (5)  [4,0,0,0]
                                    Type: List Expression Complex Integer
(6) -> h([1,2,3,4])
   (6)  [10,- 2 + 2%i,- 2,- 2 - 2%i]
                                    Type: List Expression Complex Integer
(7) -> h([5.24626,3.90746,3.72335,5.74429,4.7983,8.34171,4.46785,0.760139])
   (7)
   [36.989359, - 6.2118552150 341603904 + 0.3556612739 187363298 %i,
    1.85336 - 5.744741 %i, 7.1077752150 341603904 - 1.1333387260 812636702 %i,
    - 0.517839, 7.1077752150 341603904 + 1.1333387260 812636702 %i,
    1.85336 + 5.744741 %i,
    - 6.2118552150 341603904 - 0.3556612739 187363298 %i]
                                      Type: List Expression Complex Float
(8) -> h([%i+1,2,%i-2,9])
   (8)  [10 + 2%i,3 + 7%i,- 12 + 2%i,3 - 7%i]
                                    Type: List Expression Complex Integer

nei pochi che avevo visto h () o fft () restituiva la soluzione esatta, ma se la semplificazione non fosse buona come in:

(13) -> h([1,2,3,4,5,6,7,8])
   (13)
                    +--+                                   +--+
        (- 4 + 4%i)\|%i  - 4 + 4%i             (- 4 - 4%i)\|%i  - 4 + 4%i
   [36, --------------------------, - 4 + 4%i, --------------------------, - 4,
                    +--+                                   +--+
                   \|%i                                   \|%i
            +--+                                   +--+
    (- 4 + 4%i)\|%i  + 4 - 4%i             (- 4 - 4%i)\|%i  + 4 - 4%i
    --------------------------, - 4 - 4%i, --------------------------]
                +--+                                   +--+
               \|%i                                   \|%i
                                    Type: List Expression Complex Integer

quindi basta cambiare il tipo di un solo elemento della lista, come nella scrittura seguente 8. (Float) per trovare la soluzione approssimativa:

(14) -> h([1,2,3,4,5,6,7,8.])
   (14)
   [36.0, - 4.0000000000 000000001 + 9.6568542494 923801953 %i, - 4.0 + 4.0 %i,
    - 4.0 + 1.6568542494 92380195 %i, - 4.0, - 4.0 - 1.6568542494 92380195 %i,
    - 4.0 - 4.0 %i, - 4.0 - 9.6568542494 923801953 %i]
                                      Type: List Expression Complex Float

L'ho scritto, ho visto tutte le altre risposte perché nel link la pagina era troppo difficile, quindi non so se questo codice può essere giusto. Non sono un esperto di FFT, quindi tutto questo (è probabile) essere sbagliato.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.