Calcola la trasformata discreta di Fourier


9

Implementa la trasformata discreta di Fourier (DFT) per una sequenza di qualsiasi lunghezza. Questo può essere implementato come una funzione o un programma e la sequenza può essere fornita come argomento o usando input standard.

L'algoritmo calcolerà un risultato basato su DFT standard nella direzione in avanti. La sequenza di input ha lunghezza Ned è composta da [x(0), x(1), ..., x(N-1)]. La sequenza di output avrà la stessa lunghezza e consiste nel punto in [X(0), X(1), ..., X(N-1)]cui ciascuno X(k)è definito dalla relazione seguente.

DFT

Regole

  • Questo è quindi vince la soluzione più breve.
  • Non sono ammessi builtin che calcolano il DFT in direzioni avanti o indietro (anche note come inverse).
  • Le imprecisioni in virgola mobile non verranno conteggiate nei tuoi confronti.

Casi test

DFT([1, 1, 1, 1]) = [4, 0, 0, 0]
DFT([1, 0, 2, 0, 3, 0, 4, 0]) = [10, -2+2j, -2, -2-2j, 10, -2+2j, -2, -2-2j]
DFT([1, 2, 3, 4, 5]) = [15, -2.5+3.44j, -2.5+0.81j, -2.5-0.81j, -2.5-3.44j]
DFT([5-3.28571j, -0.816474-0.837162j, 0.523306-0.303902j, 0.806172-3.69346j, -4.41953+2.59494j, -0.360252+2.59411j, 1.26678+2.93119j] = [2, -3j, 5, -7j, 11, -13j, 17]

Aiuto

C'è stata una precedente sfida per trovare il DFT usando un algoritmo FFT per sequenze con lunghezze pari a una potenza di 2. Potresti trovare alcuni trucchi che potrebbero aiutarti qui. Tieni presente che questa sfida non ti limita a nessuna complessità e richiede anche che la tua soluzione funzioni per sequenze di qualsiasi lunghezza.

Risposte:


2

Gelatina , 16 15 byte

LR’µ×'÷L-*²³÷S€

Provalo online!

Come funziona

LR’µ×'÷L-*²³÷S€  Main link. Argument [x(0), ..., x(N-1)].

L                Length; yield N.
 R               Range; yield [1, ..., N].
  ’              Decrement; yield [0, ..., N-1].
   µ             Begin a new, monadic chain. Argument: [0, ..., N-1]
    ×'           Spawned multiply [0, ..., N-1] with itself, yielding the matrix
                 of all possible products k×n.
      ÷L         Divide each product by N.
        -*       Compute (-1)**(kn÷L) for each kn.
          ²      Square each result, computing (-1)**(2kn÷L).
           ³÷    Divide [x(0), ..., x(N-1)] by the results.
             S€  Compute the sum for each row, i.e., each X(k).


5

Python 3, 77 byte

lambda x,e=enumerate:[sum(t/1j**(4*k*n/len(x))for n,t in e(x))for k,_ in e(x)]

Provalo su Ideone .

Il codice utilizza la formula equivalente

formula


Wow, figure gigantesche. È bello vedere le formule equivalenti che possono consentire codici più brevi.
miglia,

4

J, 30 20 byte

3 byte grazie a @miles .

Usa il fatto che e^ipi = -1.

La formula diventa X_k = sum(x_n / ((-1)^(2nk/N))).

+/@:%_1^2**/~@i.@#%#

uso

>> DCT =: +/@:%_1^2**/~@i.@#%#
>> DCT 1 2 3 4 5
<< 15 _2.5j3.44095 _2.5j0.812299 _2.5j_0.812299 _2.5j_3.44095

dove >>è STDIN ed <<è STDOUT.

"Le imprecisioni in virgola mobile non verranno conteggiate nei tuoi confronti."


3

MATL , 20 16 byte

-1yn:qt!Gn/E*^/s

L'input è un vettore di colonna, ovvero sostituisce le virgole con punti e virgola:

[1; 1; 1; 1]
[1; 0; 2; 0; 3; 0; 4; 0]
[1; 2; 3; 4; 5]
[5-3.28571j; -0.816474-0.837162j; 0.523306-0.303902j; 0.806172-3.69346j; -4.41953+2.59494j; -0.360252+2.59411j; 1.26678+2.93119j] 

Questo utilizza la formula nella risposta di Leaky Nun , basata sui fatti che exp ( ) = −1 e che l'operatività di potenza di MATL con esponente non intero produce (come nella maggior parte dei linguaggi di programmazione) il risultato del ramo principale .

Provalo online!

A causa della strana spaziatura di Octave con numeri complessi, le parti reali e immaginarie sono separate da uno spazio, così come le diverse voci del vettore risultante. Se sembra troppo brutto, aggiungi un !alla fine ( 17 byte ) per avere ogni voce dell'output in una riga diversa.

Spiegazione

-1      % Push -1
y       % Get input implicitly. Push a copy below and one on top of -1
n:q     % Row vector [0 1 ... N-1] where N is implicit input length
t!      % Duplicate and transpose: column vector
Gn      % Push input length
/       % Divide
E       % Multiply by 2
*       % Multiply, element-wise with broadcast. Gives the exponent as a matrix
^       % Power (base is -1), element-wise. Gives a matrix
/       % Divide matrix by input (column vector), element-wise with broadcast
s       % Sum

2

Pyth, 30

ms.e*b^.n1****c_2lQk.n0d.j0)QU

Test Suite

Approccio molto ingenuo, solo un'implementazione della formula. Si imbatte in vari problemi minori in virgola mobile con valori che dovrebbero essere additivi inverse aggiungendo il risultato in valori leggermente diversi da zero.

Stranamente .jnon sembra funzionare senza argomenti, ma non sono sicuro se lo sto usando correttamente.


1
Complimenti per 10k !!
Luis Mendo,



2

Python 2, 78 byte

l=input();p=1
for _ in l:print reduce(lambda a,b:a*p+b,l)*p;p*=1j**(4./len(l))

Il polinomio viene valutato per ogni potenza pdi 1j**(4./len(l)).

L'espressione reduce(lambda a,b:a*p+b,l)valuta il polinomio dato dal lvalore ptramite il metodo di Horner:

reduce(lambda a,b:a*10+b,[1,2,3,4,5])
=> 12345

Tranne che, l'elenco di input fuori è invertito, con termine costante alla fine. Potremmo invertirlo, ma perché p**len(l)==1per i coefficienti di Fourier, possiamo usare un hack di invertire pe moltiplicare l'intero risultato per p.

Alcuni tentativi di uguale lunghezza:

l=input();i=0
for _ in l:print reduce(lambda a,b:(a+b)*1j**i,l,0);i+=4./len(l)

l=input();i=0
for _ in l:print reduce(lambda a,b:a*1j**i+b,l+[0]);i+=4./len(l)

Come funzione per 1 byte in più (79):

lambda l:[reduce(lambda a,b:a*1j**(i*4./len(l))+b,l+[0])for i in range(len(l))]

Un tentativo di ricorsione (80):

f=lambda l,i=0:l[i:]and[reduce(lambda a,b:(a+b)*1j**(i*4./len(l)),l,0)]+f(l,i+1)

Simulazione iterativa reduce(80):

l=input();p=1;N=len(l)
exec"s=0\nfor x in l:s=s*p+x\nprint s*p;p*=1j**(4./N);"*N

2

C (gcc) , 86 78 byte

k;d(a,b,c)_Complex*a,*b;{for(k=c*c;k--;)b[k/c]+=a[k%c]/cpow(1i,k/c*k%c*4./c);}

Provalo online!

Ciò presuppone che il vettore di output sia azzerato prima dell'uso.


1

Python 2, 89 byte

Usa il fatto che e^ipi = -1.

La formula diventa X_k = sum(x_n / ((-1)^(2nk/N))).

lambda a:[sum(a[x]/(-1+0j)**(x*y*2./len(a))for x in range(len(a)))for y in range(len(a))]

Ideone esso!


Pubblica questo come una risposta separata!
Leaky Nun,

Va bene, se lo dici tu.
Dennis,

1

Mathematica, 49 48 47 byte

Total[I^Array[4(+##-##-1)/n&,{n=Length@#,n}]#]&

Basato sulla formula della soluzione di @Dennis .


1

Assioma, 81 byte

g(x)==(#x<2=>x;[reduce(+,[x.j/%i^(4*k*(j-1)/#x)for j in 1..#x])for k in 0..#x-1])

usando la formula che qualcuno pubblica qui. risultati

(6) -> g([1,1,1,1])
   (6)  [4,0,0,0]
                                    Type: List Expression Complex Integer
(7) -> g([1,2,3,4])
   (7)  [10,- 2 + 2%i,- 2,- 2 - 2%i]
                                    Type: List Expression Complex Integer
(8) -> g([1,0,2,0,3,0,4,0])
   (8)  [10,- 2 + 2%i,- 2,- 2 - 2%i,10,- 2 + 2%i,- 2,- 2 - 2%i]
                                    Type: List Expression Complex Integer
(11) -> g([1,2,3,4,5])
   (11)
        5+--+4       5+--+3    5+--+2      5+--+
        \|%i   + 5%i \|%i   - 4\|%i   - 3%i\|%i  + 2
   [15, --------------------------------------------,
                           5+--+4
                           \|%i
    5+--+4       5+--+3    5+--+2      5+--+
    \|%i   + 3%i \|%i   - 5\|%i   - 2%i\|%i  + 4
    --------------------------------------------,
                       5+--+4
                       \|%i
    5+--+4       5+--+3    5+--+2      5+--+
    \|%i   + 4%i \|%i   - 2\|%i   - 5%i\|%i  + 3
    --------------------------------------------,
                       5+--+4
                       \|%i
    5+--+4       5+--+3    5+--+2      5+--+
    \|%i   + 2%i \|%i   - 3\|%i   - 4%i\|%i  + 5
    --------------------------------------------]
                       5+--+4
                       \|%i
                                    Type: List Expression Complex Integer
(12) -> g([1,2,3,4,5.])
   (12)
   [15.0, - 2.5 + 3.4409548011 779338455 %i, - 2.5 + 0.8122992405 822658154 %i,
    - 2.5 - 0.8122992405 822658154 %i, - 2.5 - 3.4409548011 779338455 %i]
                                      Type: List Expression Complex Float

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.