Quá nhanh, quá Fourier: FFT Code Golf


48

Thực hiện Biến đổi Fourier nhanh trong ít nhân vật nhất có thể.

Quy tắc:

  • Giải pháp ngắn nhất sẽ thắng
  • Có thể giả định rằng đầu vào là mảng 1D có độ dài bằng hai.
  • Bạn có thể sử dụng thuật toán bạn chọn, nhưng giải pháp thực sự phải là Biến đổi Fourier nhanh, không chỉ là Biến đổi Fourier rời rạc ngây thơ (nghĩa là nó phải có chi phí tính toán tiệm cận của )O(NlogN)

Biên tập:

  • mã phải thực hiện Chuyển đổi Fourier nhanh chuyển tiếp tiêu chuẩn, hình thức có thể được nhìn thấy trong phương trình (3) của bài viết Wolfram này ,

    nhập mô tả hình ảnh ở đây

  • Không được phép sử dụng chức năng FFT từ thư viện tiêu chuẩn hoặc gói thống kê tiêu chuẩn. Thách thức ở đây là thực hiện ngắn gọn chính thuật toán FFT.

3
Điều này là không xác định. Ít nhất bạn cần xác định các yếu tố chuẩn hóa, và bạn cũng nên lưu ý rằng bất kỳ sự mơ hồ nào cũng sẽ bị hiểu sai một cách cố ý. Ví dụ: "Thực hiện" được thỏa mãn bởi câu trả lời " FFT(3 ký tự): nó có trong thư viện chuẩn" không? Một số trường hợp thử nghiệm cũng sẽ tốt.
Peter Taylor

Có vấn đề gì về thứ tự của các phần tử đầu ra không, tức là chúng ta có cần thực hiện đảo ngược bit hay chúng ta có thể để đầu ra theo thứ tự xáo trộn không?
Paul R

Xem các chỉnh sửa cho các quy tắc. Đầu ra phải là một danh sách / mảng với các giá trị được sắp xếp theo các chỉ số trong biểu thức DFT tiêu chuẩn, được tham chiếu ở trên.
jakevdp

2
Bạn có thể đăng một số ví dụ đầu vào và đầu ra để chúng tôi có thể kiểm tra việc triển khai của chúng tôi không?
FUZxxl

2
Tiêu đề nên là "Nhanh và Fourier-s" (Nhanh và tức giận).
clismique

Câu trả lời:


12

Toán học, 95 byte

Một triển khai khác của Cooley Thẻ Tukey FFT với sự giúp đỡ từ @ chyaong .

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

Ung dung

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
Tôi nghĩ #[[;;;;2]]==#[[1;;N;;2]][[2;;;;2]]==[[2;;N;;2]].
chyanog

1
101 ký tự With[{L=Length@#},If[L>1,Join[+##,#-#2]&[#0@#[[;;;;2]],#0@#[[2;;;;2]]E^(-2I*Pi(Range[L/2]-1)/L)],#]]&
Giới thiệu

Thật tuyệt, bạn có thể ngưng tụ một hàm ẩn danh khác bên trong nó mà không xung đột với hàm đệ quy. Cũng học được rằng Phần điền vào các chỉ số bị thiếu. Chúng ta có thể đưa nó đi xa hơn bằng cách sử dụng Unicode.
dặm

9

J, 37 byte

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

Một sự cải thiện sau một vài năm. Vẫn sử dụng thuật toán Cooley-Tukey FFT.

Đã lưu 4 byte bằng e πi = -1, nhờ @ Leaky Nun .

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

Sử dụng

   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

Giải trình

_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


9

Con trăn, 166 151 150 ký tự

Điều này sử dụng thuật toán FFT radix-2 Cooley-Tukey

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

Kiểm tra kết quả

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

1
2 điều: nó thường tốt nhất để sử dụng from x import*sum(([x for x in y] for y in z),[])dài hơn [x for y in z for x in y].
gian hàng

1
Cảm ơn - tiết kiệm 15 ký tự! 11 nữa và đó là một tweet.
jakevdp

Ồ, điều đó chắc chắn là có thể. Thông thường khi bạn tìm thấy một cải tiến, một cái cũ trở thành một vấp ngã.
gian hàng

5

Python 3: 140 134 113 ký tự

Phiên bản ngắn - phù hợp ngắn và ngọt ngào, trong một tweet (với nhờ dặm ):

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

(Trong Python 2, /là phép chia cắt khi cả hai bên là số nguyên. Vì vậy, chúng tôi thay thế (i*4/n)bằng cách thay đổi (i*4.0/n)độ dài thành 115 ký tự.)

Phiên bản dài - rõ ràng hơn vào phần bên trong của FFT Cooley-Tukey cổ điển:

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
Rút ngắn xuống còn 113 byte sử dụnge^(-2j * pi * i / n) = (-1)^(2 * i / n) = (1j)^(4 * i / n)
dặm

@miles Quan sát rất ấn tượng, cảm ơn bạn! Đã nhiều lần thực hiện các DFT trong hơn một thập kỷ, tôi bị ám ảnh bởi sin / cos / exp và quên rằng có thể sử dụng các năng lực đơn giản của tôi. Tôi đã chỉnh sửa câu trả lời của mình để kết hợp cái nhìn sâu sắc mới và ghi nhận bạn.
Nayuki

5

R: 142 133 99 95 byte

Cảm ơn @Giuseppe đã giúp tôi cạo xuống 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)

Một mẹo bổ sung ở đây là sử dụng các đối số mặc định của hàm chính để khởi tạo một số biến.
Cách sử dụng vẫn như cũ:

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

Phiên bản 4 tuổi ở 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}}

Với vết lõm:

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

Nó cũng sử dụng thuật toán Cooley-Tukey. Các thủ thuật duy nhất ở đây là sử dụng hàm Recallcho phép đệ quy và sử dụng vectơ R rút ngắn rất nhiều tính toán thực tế.

Sử dụng:

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

1
Bốn năm sau, và chúng tôi giảm xuống còn 101 byte . Không chắc chắn 100% lý do tại sao bạn đã sử dụng Recallnhư một chức năng đã được đặt tên, nhưng này, thật dễ dàng để chơi golf trong nhận thức muộn! :) +1, rất hay.
Giuseppe

Recalllà bây giờ không cần thiết, thực sự. Tôi nhận thấy rằng một vài tháng trước nhưng quá lười để thay đổi nó :) Tôi sẽ sửa đổi nó.
plannapus

Rất đẹp! Tôi vắt thêm 4 byte! , đặt điều này ngang hàng với Mathicala.
Giuseppe

Cảm ơn! Tôi nghĩ về việc đưa ylên đó nhưng không nhận thấy nó cũng có thể được sử dụng cho exp(...)một phần.
plannapus

4

Con trăn, 134

Điều này vay mượn rất nhiều từ giải pháp của jakevdp, vì vậy tôi đã đặt cái này thành wiki cộng đồng.

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

Thay đổi:

-12 ký tự: giết 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 char: lừa số mũ, x*y**-z == x/y**z (điều này có thể giúp một số người khác)

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

-2 char: thay thế andbằng*

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

+1 char: lambdaize, giết chócN

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 char: sử dụng enumeratethay vìzip(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])))]

Tôi nghĩ rằng đây không còn là một biến đổi phạm vi nhanh, mặc dù ... bằng cách "giết chết" bạn đã thêm vào một số tính toán không cần thiết để chuyển nó từ O [N log (N)] sang O [N ^ 2]
jakevdp

Có vẻ như tôi không thể tải xuống bài viết của mình. Bạn đã đúng, tôi đã trao đổi thứ tự vòng lặp và giết hiệu suất. Tôi sẽ để nó bây giờ, trong trường hợp tôi tìm cách sửa nó.
gian hàng

101 byte vớif=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))]
dặm

Bạn có thể thay thế for s in(1,-1)forbằng for s in 1,-1forhoặc thậm chí, nếu thứ tự không quan trọng , 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;
}}}

Vấn đề là, việc triển khai như vậy là vô ích, và thuật toán đơn giản là NHIỀU nhanh hơn.


2
Bạn có thể xóa thêm một số khoảng trắng để có số lượng ký tự thấp hơn, ví dụ: step < ncó thể thay đổi thành step<nstep * 2có thể thay đổi thành step*2.
Chương trìnhFOX

2
tất cả các biến và hàm và typedefs phải có tên một chữ cái để lưu rất nhiều ký tự

2
Bạn đã có người đề xuất một loạt các cải tiến cho việc này. Hãy xem chúng ở đây: codegolf.stackexchange.com/review/suggested-edits/17119
Justin

1
Bạn có thể xóa tất cả các dòng mới, dòng mới là vô dụng trong C
TuxCrafting

@ TùxCräftîñg Không phải tất cả các dòng mới đều vô dụng. Chúng cần thiết cho các chỉ thị như #include, #define, #if, v.v.
Nayuki

3

Matlab, 128 118 107 102 101 94 93 byte

EDIT6: cảm ơn @algmyr cho một byte khác!

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: Vẫn ngày càng ngắn hơn :) nhờ @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 ký tự nữa (có thể đã được thực hiện mà không có 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: Cảm ơn @sanchises vì ​​những cải tiến hơn nữa!

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: Có thể thực hiện một số cải tiến và nhận thấy rằng hằng số tỷ lệ là không bắt buộc.

Đây là phiên bản mở rộng, số lượng ký tự là hợp lệ nếu bạn xóa dòng mới / dấu cách. (Chỉ hoạt động cho các vectơ cột.)

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

Mẹo: bạn có thể kết hợp hai d=dòng thành một : m=n/2;d=f(Y(2:2:n)).*exp(-pi*i*(0:m-1)/m).';. Hơn nữa, xem xét thay đổi y=f(Y)để Y=f(Y)và loại bỏ dòng 3 (và hứa với em sẽ không bao giờ làm điều đó bên ngoài của mã golf)
Sanchises

Ồ cảm ơn! Có function Y = f(Y)bất kỳ nhược điểm nào khác ngoài việc không đọc được không?
flawr

Chà, MATLAB sẽ không bao giờ phàn nàn về giá trị trả về, ngay cả khi Y không bao giờ thay đổi. Nó là hơi nhanh hơn mặc dù, vì vậy tôi đoán nó không phải là quá xấu sau khi tất cả đối với một số mục đích (tức là một chức năng mà hầu như không bao giờ thay đổi biến đầu vào)
Sanchises

Bây giờ, để cạo đi nhiều hơn: m=n/2có thể được gỡ bỏ, và thay vào đó mthay thế bằng n/2n*2tương ứng. Và sau đó, tôi tin tưởng mạnh mẽ, chương trình này ngắn nhất có thể trong MATLAB.
Chiếm

1
Và sau đó, tôi tin tưởng mạnh mẽ, chương trình này ngắn nhất có thể trong MATLAB. - Sanchises 8 tháng 3 '15 lúc 21:05 Những lời cuối cùng nổi tiếng ...
Sanchise

2

Jelly, 31 30 28 26 byte , không cạnh tranh

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

Jelly được tạo ra sau thử thách này nên không cạnh tranh.

Điều này sử dụng thuật toán đệ quy Cooley-Tukey radix-2. Đối với một phiên bản không chơi gôn, xem câu trả lời của tôi trong Mathicala .

Dùng thử trực tuyến hoặc Xác minh nhiều trường hợp thử nghiệm .

Giải trình

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));}

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

Hơi ít chơi 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 ký tự

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

Sử dụng

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
Đây không phải là DFT ngây thơ sao? (tức là theta (N ^ 2))
dặm

1

Octave , 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)}())

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

Ooooo làm mắt tôi chảy máu từ lambda đệ quy này . Phần lớn của điều này đã được dỡ bỏ từ câu trả lời của @ 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
)

Tôi không hiểu những gì bạn đã làm nhưng tôi thích nó rất nhiều.
flawr

0

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

Ngay cả khi h (a) có thể vượt qua tất cả các bài kiểm tra và sẽ ổn khi tham gia vào 'cuộc thi' này, người ta phải gọi h () hoặc hlp () thru fft () bên dưới, cho kiểm tra các đối số . Tôi không biết phần mềm này có ổn không vì tôi chỉ thấy những gì người khác viết và tìm kiếm cách nó có thể chạy trong Axiom để trả về một số kết quả đúng có thể. Dưới đây mã không có ý kiến ​​với một vài bình luận:

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

trong một số ít tôi đã thấy h () hoặc fft () sẽ trả về giải pháp chính xác, nhưng nếu việc đơn giản hóa không tốt như trong:

(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

hơn là thay đổi loại chỉ một yếu tố của danh sách, như trong văn bản dưới đây 8. (Float) để tìm giải pháp gần đúng:

(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

Tôi đã viết nó, thấy tất cả các câu trả lời khác bởi vì trong liên kết, trang đó quá khó khăn nên tôi không biết liệu mã này có đúng không. Tôi không phải là một chuyên gia fft nên tất cả những điều này có thể (có thể xảy ra) là sai.


0

APL (NARS), 58 ký tự, 116 byte

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

kiểm tra

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