너무 빨리, 너무 푸리에 : FFT 코드 골프


48

가능한 한 적은 문자로 고속 푸리에 변환을 구현하십시오.

규칙 :

  • 최단 솔루션 승리
  • 입력은 길이가 2의 거듭 제곱 인 1D 배열이라고 가정 할 수 있습니다.
  • 선택한 알고리즘을 사용할 수 있지만 솔루션은 실제로 순진 이산 푸리에 변환이 아니라 고속 푸리에 변환이어야합니다 (즉, 점근 적 계산 비용이 이어야 )O(NlogN)

편집하다:

  • 이 코드는 표준 포워드 고속 푸리에 변환을 구현해야하며,이 형식은 이 Wolfram 기사 의 식 (3)에서 볼 수 있습니다 .

    여기에 이미지 설명을 입력하십시오

  • 기존 표준 라이브러리 또는 통계 패키지에서 FFT 기능을 사용할 수 없습니다. 여기서의 과제 는 FFT 알고리즘 자체 를 간결하게 구현 하는 것입니다.

3
이것은 지정되지 않았습니다. 최소한 정규화 요소를 정의해야하며 모호성이 고의적으로 잘못 해석 될 것임을 알아야합니다. 예를 들어, "구현"은 " FFT(3 자) : 표준 라이브러리에 있습니다" 라는 대답으로 만족 됩니까? 일부 테스트 사례도 좋습니다.
피터 테일러

출력 요소의 순서가 중요합니까? 즉, 비트 반전 디 스크램블링을 구현해야합니까? 아니면 출력을 스크램블 된 순서로 남겨 둘 수 있습니까?
Paul R

규칙 편집 내용을 참조하십시오. 출력은 위에서 참조한 표준 DFT 표현식의 색인에 따라 정렬 된 값을 가진 목록 / 배열이어야합니다.
jakevdp

2
구현을 테스트 할 수 있도록 예제 입력 및 출력을 게시 할 수 있습니까?
FUZxxl

2
제목은 "Fast and Fourier-s"(Fast and Furious) 여야합니다.
clismique

답변:


12

Mathematica, 95 바이트

@ chyaong의 도움을 받아 Cooley–Tukey FFT를 구현 했습니다 .

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

언 골프

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
나는 생각 #[[;;;;2]]==#[[1;;N;;2]]하고 [[2;;;;2]]==[[2;;N;;2]].
chyanog

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

재귀와 충돌하지 않고 다른 익명 함수를 압축 할 수 있습니다. 또한 부품이 누락 된 인덱스를 채운다는 것을 알았습니다. 유니 코드를 사용하여 더 가져올 수 있습니다.
마일

9

J, 37 바이트

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

몇 년 후 개선. 여전히 Cooley-Tukey FFT 알고리즘을 사용합니다.

@ Leaky Nun 덕분에 e πi = -1을 사용하여 4 바이트를 절약했습니다 .

온라인으로 사용해보십시오!

용법

   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

설명

_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
또한보십시오 : blog.ndpar.com/2014/10/11/dft-j
FUZxxl

9

파이썬 166 151 150 자

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

결과 테스트

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

1
2 일 : 그것은 사용하는 것이 일반적으로 가장 좋은 from x import*, 그리고 sum(([x for x in y] for y in z),[])이상이다 [x for y in z for x in y].
boothby

1
감사합니다-15자를 절약 할 수 있습니다! 11 개 그리고 트윗입니다.
jakevdp

오, 확실히 가능합니다. 종종 하나의 개선점을 찾으면 오래된 것이 걸림돌이됩니다.
부스

5

파이썬 3 : 140 134 113 자

짧은 버전-짧고 달콤하며 트윗에 적합합니다 ( 마일 덕분에 ).

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

(Python 2에서는 /양쪽이 정수일 때 나누기가 잘립니다. 따라서 우리 는 길이를 115 문자로 범프하는로 대체 (i*4/n)됩니다 (i*4.0/n).)

긴 버전-클래식 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
e^(-2j * pi * i / n) = (-1)^(2 * i / n) = (1j)^(4 * i / n)
마일을

@ 마일 매우 인상적인 관찰 감사합니다! 10 년 넘게 DFT를 반복해서 구현 한 결과 sin / cos / exp에 집착하여 단순한 i의 힘을 사용할 수 있다는 것을 잊었습니다. 새로운 통찰력과 당신을 인정하기 위해 내 답변을 편집했습니다.
Nayuki

5

R : 142 133 99 95 바이트

32 36 바이트 를 줄인 @Giuseppe 에게 감사드립니다 !

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)

여기서 추가 트릭은 기본 함수 기본 인수를 사용하여 일부 변수를 인스턴스화하는 것입니다.
사용법은 여전히 ​​동일합니다.

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

133 바이트의 4 년 된 버전 :

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

들여 쓰기

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

Cooley-Tukey 알고리즘도 사용합니다. 여기서 유일한 트릭 Recall은 재귀를 허용 하는 함수 와 실제 계산을 크게 단축시키는 R 벡터화를 사용하는 것입니다.

용법:

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

1
4 년 후 101 바이트로 줄 였습니다. 왜 Recall이미 명명 된 함수로 사용했는지 100 % 확실 하지는 않지만, 뒤늦게 골프를 치는 것은 쉬운 일입니다! :) +1, 아주 좋습니다.
주세페

Recall참, 지금은 필요하지 않습니다. 나는 몇 달 전에 그것을 알아 차리기에는 너무 게으르다는 것을 알았습니다. :) 수정하겠습니다.
plannapus

아주 좋아요! 나는 또 다른 4 바이트를냈다! , 이것을 Mathematica와 동등하게합니다.
주세페

감사! 나는 y거기 에 올리는 것에 대해 생각 했지만 그 exp(...)부분 에도 사용할 수 있다는 것을 알지 못했습니다 .
plannapus

4

파이썬, 134

이것은 jakevdp의 솔루션에서 많은 돈을 빌리므로 이것을 커뮤니티 위키로 설정했습니다.

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

변경 사항 :

-12 자 : kill 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 : 지수 트릭 x*y**-z == x/y**z (일부 다른 사람들을 도울 수 있음)

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

-2 문자 : 교체 and와 함께*

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

+1 문자 : lambdaize, killingN

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 문자 : enumerate대신 사용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])))]

나는 이것이 더 이상 빠른 푸리에 변환이 아니라고 생각한다. "killing t"에 의해 O [N log (N)]에서 O [N ^ 2]로 이동하는 불필요한 계산을 추가했다.
jakevdp

내 게시물을 공감할 수없는 것 같습니다. 당신은 맞습니다, 나는 루프 순서를 교환하고 성능을 죽였습니다. 내가 고칠 수있는 방법을 찾은 경우에 대비하여 지금은 그대로 두겠습니다.
boothby

101 바이트f=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))]
마일

당신은 대체 할 수 for s in(1,-1)forfor s in 1,-1for순서가 중요하지 않은 경우, 심지어 나 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;
}}}

문제는 그러한 구현이 쓸모없고 간단한 알고리즘이 훨씬 빠르다는 것입니다.


2
더 많은 공백을 제거하여 더 적은 수의 문자를 얻을 step < n수 있습니다 ( 예 : 로 변경 step<nstep * 2로 변경 가능) step*2.
ProgramFOX

2
모든 변수와 함수 및 typedef는 많은 문자를 저장하기 위해 한 글자의 이름을

2
당신은 누군가 이것을 위해 많은 개선을 제안했습니다. 여기를 살펴보십시오 : codegolf.stackexchange.com/review/suggested-edits/17119
저스틴

1
모든 줄 바꿈을 제거 할 수 있습니다. 줄 바꿈은 C에서 쓸모가 없습니다.
TuxCrafting

@ TùxCräftîñg 모든 개행 문자가 쓸모있는 것은 아닙니다. #include, #define, #if 등과 같은 지시문에 필요합니다.
Nayuki

3

MATLAB, 128 118 107 102 101 94 93 바이트

EDIT6 : 다른 바이트에 대한 @algmyr 감사합니다!

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 : @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 : 예, -1 문자 이상 ( 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 : 추가 개선을위한 @sanchises에 감사드립니다!

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

편집 : 약간의 개선이 있었으며 스케일링 상수가 필요하지 않은 것으로 나타났습니다.

이것은 확장 버전이며 줄 바꿈 / 공백을 제거하면 문자 수가 유효합니다. (열 벡터에만 적용됩니다.)

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

팁 : 두 d=줄을 하나로 결합 할 수 있습니다 m=n/2;d=f(Y(2:2:n)).*exp(-pi*i*(0:m-1)/m).';. 또한 3 행으로 변경 및 제거 y=f(Y)를 고려 Y=f(Y)하십시오 (코드 골프 외부에서는 절대로 그렇게하지 않겠다고 약속하십시오)
Sanchises

오 감사! 않습니다 function Y = f(Y)unreadability 이외의 disadvanteages이?
flawr

음, MATLAB은 Y가 변경되지 않아도 반환 값에 대해 불평하지 않습니다. 그것은 조금 더 빠르기 때문에 어떤 목적 (예 : 입력 변수를 거의 변경하지 않는 함수)으로 인해 그렇게 나쁘지는 않다고 생각합니다.
Sanchises

이제 더 많은 m=n/2것을 제거하기 위해 제거 할 수 있으며 대신 및로 각각 m대체 될 수 있습니다 . 그런 다음 프로그램은 MATLAB에서 가능한 한 짧습니다. n/2n*2
Sanchises

1
그런 다음 프로그램은 MATLAB에서 가능한 한 짧습니다. – Sanchises 3 월 8 일 15시 21:05 유명한 마지막 단어 ...
Sanchises

2

젤리, 31 30 28 26 바이트 , 비경쟁

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

젤리는이 도전 이후에 만들어 졌으므로 경쟁이 아닙니다.

Cooley-Tukey 기수 -2 재귀 알고리즘을 사용합니다. 골프 용 버전 은 Mathematica의 답변 을 참조하십시오 .

온라인으로 시도 하거나 여러 테스트 사례를 확인하십시오 .

설명

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) 바이트

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

온라인으로 사용해보십시오!

약간 덜 골프

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

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

용법

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
이것이 순진한 DFT 아닌가요? (즉, 세타 (N ^ 2))
마일

1

옥타브 , 109103101100 바이트

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

온라인으로 사용해보십시오!

Ooooo는이 재귀 적발 람다 에서 내 눈을 피 합니다. 이것의 대부분은 @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
)

나는 당신이 한 일을 이해하지 못하지만 그것을 많이 좋아합니다.
flawr

0

공리, 259 , 193 , 181 , 179 바이트

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

비록 h (a)가 모든 테스트를 통과 할 수 있고이 '경쟁'에 대한 항목으로 괜찮을지라도 인수확인 하기 위해 아래의 hft ()를 통해 fft ()를 호출해야 합니다. 다른 소프트웨어가 무엇인지 보았 기 때문에이 소프트웨어가 정상인지 알 수 없으며 Axiom에서 실행할 수있는 방법을 검색하여 가능한 올바른 결과를 반환합니다. 주석이 거의없는 ungolfed 코드 아래 :

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

몇 가지에서 h () 또는 fft ()가 정확한 솔루션을 반환하는 것을 보았지만 단순화가 좋지 않은 경우 :

(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

아래의 8을 쓰는 것처럼 대략적인 해결책을 찾기 위해리스트의 한 요소의 유형 만 변경하면 충분합니다.

(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

링크에서 페이지가 너무 어려워서이 코드가 올바른지 알 수 없기 때문에 다른 모든 답변을 보았습니다. 나는 한 fft 전문가가 아니기 때문에이 모든 것이 잘못되었을 수 있습니다.


0

APL (NARS), 58 자, 116 바이트

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

테스트

  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 
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.