Tính toán biến đổi Fourier rời rạc


9

Thực hiện Biến đổi Fourier rời rạc (DFT) cho một chuỗi có độ dài bất kỳ. Điều này có thể được thực hiện như là một hàm hoặc một chương trình và chuỗi có thể được đưa ra dưới dạng đối số hoặc sử dụng đầu vào tiêu chuẩn.

Thuật toán sẽ tính toán một kết quả dựa trên DFT tiêu chuẩn theo hướng chuyển tiếp. Trình tự đầu vào có chiều dài Nvà bao gồm [x(0), x(1), ..., x(N-1)]. Chuỗi đầu ra sẽ có cùng độ dài và bao gồm [X(0), X(1), ..., X(N-1)]mỗi nơi X(k)được xác định bởi mối quan hệ bên dưới.

DFT

Quy tắc

  • Đây là nên giải pháp ngắn nhất sẽ thắng.
  • Không được phép xây dựng các tính toán DFT theo hướng tiến hoặc lùi (còn được gọi là nghịch đảo).
  • Không chính xác điểm nổi sẽ không được tính vào bạn.

Các trường hợp thử nghiệm

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]

Cứu giúp

Có một thử thách trước đây để tìm DFT bằng thuật toán FFT cho các chuỗi có độ dài bằng với sức mạnh là 2. Bạn có thể tìm thấy một số thủ thuật có thể giúp bạn ở đây. Hãy nhớ rằng thử thách này không giới hạn bạn trong bất kỳ sự phức tạp nào và cũng yêu cầu giải pháp của bạn hoạt động cho các chuỗi có độ dài bất kỳ.

Câu trả lời:


2

Thạch , 16 15 byte

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

Hãy thử trực tuyến!

Làm thế nào nó hoạt động

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

Kiểm tra nó trên Ideone .

Mã sử ​​dụng công thức tương đương

công thức


Wow, con số hài hước. Thật tuyệt khi thấy các công thức tương đương có thể cho phép mã ngắn hơn.
dặm

4

J, 30 20 byte

3 byte nhờ @miles .

Sử dụng thực tế rằng e^ipi = -1.

Công thức trở thành X_k = sum(x_n / ((-1)^(2nk/N))).

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

Sử dụng

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

>>STDIN ở đâu và <<là STDOUT.

"Không chính xác điểm nổi sẽ không được tính vào bạn."


3

MATL , 20 16 byte

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

Đầu vào là một vectơ cột, tức là thay thế dấu phẩy bằng dấu chấm phẩy:

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

Điều này sử dụng công thức trong câu trả lời của Leaky Nun , dựa trên các sự kiện exp ( ) = −1, và toán hạng công suất của MATL với số mũ không nguyên số (như trong hầu hết các ngôn ngữ lập trình) kết quả nhánh chính .

Hãy thử trực tuyến!

Do khoảng cách kỳ lạ của Octave với các số phức, phần thực và phần ảo được phân tách bằng một khoảng trắng, cũng như các mục khác nhau của vectơ kết quả. Nếu điều đó trông quá xấu xí, hãy thêm một !ở cuối ( 17 byte ) để có mỗi mục nhập của đầu ra trong một hàng khác nhau.

Giải trình

-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

Bình thường, 30

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

Phòng thử nghiệm

Cách tiếp cận rất ngây thơ, chỉ là một thực hiện của công thức. Chạy vào các vấn đề dấu phẩy động nhỏ khác nhau với các giá trị sẽ là nghịch đảo cộng gộp thêm vào dẫn đến các giá trị hơi lệch về 0.

Điều kỳ lạ .jlà dường như không hoạt động mà không có đối số, nhưng tôi không chắc liệu tôi có sử dụng đúng không.


1
Chúc mừng 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))

Đa thức được đánh giá cho mỗi sức mạnh pcủa 1j**(4./len(l)).

Biểu thức reduce(lambda a,b:a*p+b,l)đánh giá đa thức được đưa ra bởi ltrên giá trị pthông qua phương thức của Horner:

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

Ngoại trừ, danh sách đầu vào ra được đảo ngược, với thời hạn không đổi ở cuối. Chúng tôi có thể đảo ngược nó, nhưng vì p**len(l)==1hệ số Fourier, chúng tôi có thể sử dụng một hack đảo ngược pvà nhân toàn bộ kết quả bằng p.

Một số lần thử có độ dài bằng nhau:

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)

Là một hàm cho thêm 1 byte (79):

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

Một nỗ lực đệ quy (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)

Lặp lại mô phỏng 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


1

Python 2, 89 byte

Sử dụng thực tế rằng e^ipi = -1.

Công thức trở thành 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))]

Nghĩa là nó!


Gửi rằng như là một câu trả lời riêng biệt!
Rò rỉ Nun

Được rồi, nếu bạn nói như vậy.
Dennis

1

Toán học, 49 48 47 byte

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

Dựa trên công thức từ giải pháp của @Dennis .


1

Tiên đề, 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])

sử dụng công thức ai đó đăng ở đây. Các kết quả

(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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.