Hitung Transformasi Fourier Diskrit

9

Terapkan Discrete Fourier Transform (DFT) untuk urutan berapa pun panjangnya. Ini dapat diimplementasikan sebagai fungsi atau program dan urutannya dapat diberikan sebagai argumen atau menggunakan input standar.

Algoritma akan menghitung hasil berdasarkan DFT standar di arah maju. Urutan input memiliki panjang Ndan terdiri dari [x(0), x(1), ..., x(N-1)]. Urutan output akan memiliki panjang yang sama dan terdiri dari di [X(0), X(1), ..., X(N-1)]mana masing X(k)- masing didefinisikan oleh hubungan di bawah ini.

DFT

Aturan

  • Ini adalah sehingga solusi terpendek menang.
  • Builtin yang menghitung DFT dalam arah maju atau mundur (juga dikenal sebagai terbalik) tidak diperbolehkan.
  • Ketidaktepatan titik-mengambang tidak akan dihitung terhadap Anda.

Uji Kasus

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]

Tolong

Ada tantangan sebelumnya untuk menemukan DFT menggunakan algoritma FFT untuk urutan dengan panjang yang sama dengan kekuatan 2. Anda mungkin menemukan beberapa trik di sana yang mungkin membantu Anda di sini. Ingatlah bahwa tantangan ini tidak membatasi Anda pada kerumitan apa pun dan juga mengharuskan solusi Anda bekerja untuk urutan berapa pun panjangnya.

mil
sumber

Jawaban:

2

Jelly , 16 15 byte

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

Cobalah online!

Bagaimana itu bekerja

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).
Dennis
sumber
ninja'd :(
Leaky Nun
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)]

Uji di Ideone .

Kode menggunakan rumus yang setara

rumus

Dennis
sumber
Wow, tokoh-tokoh humongous. Sangat menyenangkan melihat rumus setara yang dapat memungkinkan untuk kode yang lebih pendek.
mil
4

J, 30 20 byte

3 byte terima kasih kepada @miles .

Menggunakan fakta itu e^ipi = -1.

Rumusnya menjadi X_k = sum(x_n / ((-1)^(2nk/N))).

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

Pemakaian

>> 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

di mana >>STDIN dan <<STDOUT.

"Ketidaktepatan titik mengambang tidak akan dihitung melawanmu."

Biarawati Bocor
sumber
3

MATL , 20 16 byte

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

Input adalah vektor kolom, yaitu ganti koma dengan titik koma:

[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] 

Ini menggunakan rumus dalam jawaban Leaky Nun , berdasarkan pada fakta bahwa exp ( ) = −1, dan bahwa operasi daya MATL dengan eksponen non-integer menghasilkan (seperti dalam kebanyakan bahasa pemrograman) hasil cabang utama .

Cobalah online!

Karena jarak aneh Oktaf dengan bilangan kompleks, bagian nyata dan imajiner dipisahkan oleh spasi, seperti juga entri yang berbeda dari vektor yang dihasilkan. Jika itu terlihat terlalu jelek, tambahkan a !di akhir ( 17 byte ) untuk memiliki setiap entri output di baris yang berbeda.

Penjelasan

-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
Luis Mendo
sumber
2

Pyth, 30

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

Test Suite

Pendekatan yang sangat naif, hanya implementasi dari formula. Berlari ke berbagai masalah titik apung kecil dengan nilai yang harus ditambahkan inverses untuk menghasilkan nilai yang sedikit dari nol.

Anehnya .jsepertinya tidak berfungsi tanpa argumen, tapi saya tidak yakin apakah saya menggunakannya dengan benar.

FryAmTheEggman
sumber
1
Selamat atas 10k !!
Luis Mendo
2

Pyth, 18 byte

Menggunakan fakta itu e^ipi = -1.

Rumusnya menjadi X_k = sum(x_n / ((-1)^(2nk/N))).

ms.ecb^_1*cyklQdQU

Suite uji.

Biarawati Bocor
sumber
2

Julia, 45 byte

~=endof
!x=sum(x./im.^(4(r=0:~x-1).*r'/~x),1)

Cobalah online!

Kode menggunakan rumus yang setara

rumus

Dennis
sumber
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))

Polinomial dievaluasi untuk setiap kekuatan pdari 1j**(4./len(l)).

Ekspresi reduce(lambda a,b:a*p+b,l)mengevaluasi polinomial yang diberikan oleh lpada nilai pmelalui metode Horner:

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

Kecuali, daftar input keluar dibalik, dengan suku konstan di akhir. Kita dapat membalikkannya, tetapi karena p**len(l)==1untuk koefisien Fourier, kita dapat menggunakan retasan pembalikan pdan mengalikan seluruh hasil dengan p.

Beberapa upaya sama panjang:

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)

Sebagai fungsi untuk 1 byte lebih banyak (79):

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

Upaya rekursi (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)

Simulasi berulang 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
Tidak
sumber
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);}

Cobalah online!

Ini mengasumsikan vektor output nol sebelum digunakan.

plafon
sumber
1

Python 2, 89 byte

Menggunakan fakta itu e^ipi = -1.

Rumusnya menjadi 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))]

Ide itu!

Biarawati Bocor
sumber
Posting itu sebagai jawaban terpisah!
Leaky Nun
Baiklah, jika Anda mengatakannya.
Dennis
1

Mathematica, 49 48 47 byte

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

Berdasarkan formula dari solusi @Dennis .

mil
sumber
1

Aksioma, 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])

menggunakan rumus yang dikirim seseorang di sini. Hasil

(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
RosLuP
sumber
0

Oktaf , 43 39 byte

@(x)j.^(-4*(t=0:(s=rows(x))-1).*t'/s)*x

Cobalah online!

Mengalikan vektor input dengan matriks DFT.

plafon
sumber