बहुत तेज़, बहुत तेज़: FFT कोड गोल्फ


48

सबसे कम संभव पात्रों में फास्ट फूरियर ट्रांसफॉर्म को लागू करें।

नियम:

  • सबसे छोटा समाधान जीतता है
  • यह माना जा सकता है कि इनपुट 1D सरणी है जिसकी लंबाई दो की शक्ति है।
  • आप अपनी पसंद के एल्गोरिथ्म का उपयोग कर सकते हैं, लेकिन समाधान वास्तव में एक फास्ट फूरियर ट्रांसफॉर्म होना चाहिए, न कि केवल एक भोली डिस्क्रीट फूरियर ट्रांसफॉर्म (यानी, इसमें हे(एनलॉग इन करेंएन) एसिम्प्टोटिक गणना लागत होनी चाहिए )

संपादित करें:

  • कोड को मानक फॉरवर्ड फास्ट फूरियर ट्रांसफॉर्म को लागू करना चाहिए, जिसके स्वरूप को इस वुल्फ्राम लेख के समीकरण (3) में देखा जा सकता है ,

    यहाँ छवि विवरण दर्ज करें

  • पहले से मौजूद मानक लाइब्रेरी या सांख्यिकी पैकेज से FFT फ़ंक्शन का उपयोग करने की अनुमति नहीं है। यहां चुनौती एफएफटी एल्गोरिदम को सफलतापूर्वक लागू करना है।

3
यह अधोमानक है। बहुत कम से कम आपको सामान्यीकरण कारकों को परिभाषित करने की आवश्यकता है, और आपको यह भी ध्यान रखना चाहिए कि किसी भी अस्पष्टता को स्पष्ट रूप से गलत समझा जाएगा। ईजी "जवाब से संतुष्ट" " FFT(3 वर्ण) है: यह मानक पुस्तकालय में है"? कुछ परीक्षण के मामले भी अच्छे होंगे।
पीटर टेलर

क्या यह आउटपुट तत्वों के क्रम के बारे में बात करता है, अर्थात क्या हमें थोड़ा उलट-पुलट करने की आवश्यकता है या क्या हम आउटपुट को तले हुए क्रम में छोड़ सकते हैं?
पॉल आर

नियमों को संपादित देखें। आउटपुट मानक डीएफटी अभिव्यक्ति में सूचकांकों के अनुसार ऑर्डर किए गए मानों के साथ एक सूची / सरणी होनी चाहिए, ऊपर संदर्भित है।
jakevdp

2
क्या आप कुछ उदाहरण इनपुट और आउटपुट पोस्ट कर सकते हैं ताकि हम अपने कार्यान्वयन का परीक्षण कर सकें?
फ़ूजज़नल

2
शीर्षक "फास्ट एंड फूरियर-एस" (फास्ट एंड फ्यूरियस) होना चाहिए था।
जिज्ञासा

जवाबों:


12

गणितज्ञ, 95 बाइट्स

Cooley-Tukey FFT का एक और कार्यान्वयन @ च्यांग की मदद से ।

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

Ungolfed

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]]
१०:१३ पर च्योग

1
101 अक्षर With[{L=Length@#},If[L>1,Join[+##,#-#2]&[#0@#[[;;;;2]],#0@#[[2;;;;2]]E^(-2I*Pi(Range[L/2]-1)/L)],#]]&
ch

अच्छा है, आप पुनरावर्ती के साथ संघर्ष किए बिना इसके अंदर एक और अनाम फ़ंक्शन को संघनित कर सकते हैं। यह भी सीखा कि पार्ट लुप्त सूचकांकों में भरता है। हम इसे यूनिकोड का उपयोग करके आगे ले जा सकते हैं।
मील

9

जे, 37 बाइट्स

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

कुछ वर्षों के बाद एक सुधार। अभी भी Cooley-Tukey FFT एल्गोरिथ्म का उपयोग करता है।

-1i = -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]
बूथबीज

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

(अजगर 2 में, /विभाजन को छोटा किया जाता है जब दोनों पक्षों पूर्णांक हैं। इसलिए हम बदलने के (i*4/n)द्वारा (i*4.0/n), जो 115 वर्ण के लिए लंबाई मुलाकात।)

लंबा संस्करण - क्लासिक कोलेली-तुकी एफएफटी के आंतरिक में अधिक स्पष्टता:

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
113 बाइट्स का उपयोग करते हुए छोटाe^(-2j * pi * i / n) = (-1)^(2 * i / n) = (1j)^(4 * i / n)
मील

@ मीलों बहुत प्रभावशाली अवलोकन, धन्यवाद! एक दशक से अधिक बार DFTs को लागू करने के बाद, मैं पाप / कॉस / ऍक्स्प से ग्रस्त हो गया और यह भूल गया कि i की सरल शक्तियों का उपयोग किया जा सकता है। मैंने नई जानकारी को शामिल करने और आपको श्रेय देने के लिए अपने उत्तर को संपादित किया।
नायुकी

5

आर: 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है जो पुनरावर्तन की अनुमति देता है और आर वेक्टरकरण का उपयोग जो वास्तविक गणना को बहुत छोटा करता है।

उपयोग:

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

1
चार साल बाद, और हम इसे 101 बाइट्स तक ले जाते हैं । 100% निश्चित नहीं है कि आपने इसका Recallनाम पहले से ही क्यों रखा है, लेकिन हे, यह आसान है कि आप इसे देख सकें! :) +1, बहुत अच्छा।
ग्यूसेप

हाँ Recallअब अनावश्यक है, वास्तव में। मैंने देखा कि कुछ महीने पहले लेकिन इसे बदलने के लिए बहुत आलसी था :) मैं इसे संशोधित करूंगा।
प्लेनपस

बहुत अच्छा! मैं एक और 4 बाइट्स बाहर निचोड़ा ! , यह गणितज्ञ के साथ बराबर पर डाल रहा है।
Giuseppe

धन्यवाद! मैंने yवहाँ लगाने के बारे में सोचा लेकिन ध्यान नहीं दिया कि इसका इस्तेमाल इस exp(...)हिस्से के लिए भी किया जा सकता है ।
प्लेनैपस

4

पायथन, 134

यह जेकवैप के समाधान से बहुत अधिक उधार लेता है, इसलिए मैंने इसे एक सामुदायिक विकि पर सेट किया है।

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 चरस: मार 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 चार: एक्सपोनेंट ट्रिक, 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, हत्याN

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

मुझे लगता है कि यह अब एक तेज़ फ़ॉयर ट्रांसफ़ॉर्म नहीं है, हालांकि ... "टी को मारकर" आपने कुछ अनावश्यक गणनाओं में जोड़ा है जो इसे ओ [एन लॉग (एन)] से ओ [एन ^ 2] तक ले जाते हैं
जेकवैप

ऐसा प्रतीत होता है कि मैं अपनी खुद की पोस्ट को डाउनवोट नहीं कर सकता। आप सही हैं, मैंने लूप ऑर्डर का आदान-प्रदान किया और प्रदर्शन को मार दिया। मैं इसे अभी के लिए छोड़ दूंगा, अगर मुझे इसे ठीक करने का कोई तरीका मिल जाए।
बूथबीज

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)forसाथ for s in 1,-1forया यहां तक ​​कि अगर आदेश कोई फर्क नहीं पड़ता, के साथ बदल सकते हैं for s in-1,1for
जोनाथन फ्रेच

4

सी, 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<nऔर step * 2इसे में बदला जा सकता है step*2
प्रोग्रामफॉक्स

2
सभी चर और फ़ंक्शंस और टाइपडेफ़ में बहुत सारे वर्णों को बचाने के लिए एक-अक्षर का नाम होना चाहिए

2
आपने किसी को इसके लिए सुधार का एक गुच्छा सुझाया था। उन पर एक नज़र डालें: codegolf.stackexchange.com/review/suggested-edits/17119
जस्टिन

1
आप सभी नई
कड़ियों

@ T @xCräftîñg नहीं सभी नए समाचार बेकार हैं। उन्हें निर्देश के लिए जरूरी है जैसे #include, #define, #if, इत्यादि
नायुकी

3

मैटलैब, 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)अपठनीयता के अलावा कोई नुकसान है?
निर्दोष

वैसे, MATLAB कभी भी रिटर्न वैल्यू के बारे में शिकायत नहीं करेगा, भले ही वाई कभी नहीं बदला जाए। हालांकि यह थोड़ा तेज़ है, इसलिए मुझे लगता है कि यह कुछ उद्देश्यों के लिए इतना बुरा नहीं है (यानी एक फ़ंक्शन जो इनपुट चर को लगभग कभी नहीं बदलता है)
Sanchises

अब, अधिक शेविंग के लिए: m=n/2हटाया जा सकता है, और इसके बजाय क्रमशः और mद्वारा प्रतिस्थापित किया जा सकता है । और फिर, मेरा दृढ़ता से मानना ​​है, कार्यक्रम उतना ही छोटा है जितना MATLAB में हो सकता है। n/2n*2
Sanchises

1
और फिर, मेरा दृढ़ता से मानना ​​है, यह कार्यक्रम उतना ही छोटा है जितना कि MATLAB में हो सकता है। - Sanchises Mar 8 '15 21:05 पर अंतिम शब्द ...
Sanchises

2

जेली, 31 30 28 26 बाइट्स , गैर-प्रतिस्पर्धात्मक

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

इस चुनौती के बाद जेली बनाई गई थी, इसलिए यह गैर-प्रतिस्पर्धात्मक है।

यह Cooley-Tukey मूलांक -2 पुनरावर्ती एल्गोरिथ्म का उपयोग करता है। एक गैर-गोल्फ संस्करण के लिए, मैथमेटिका में मेरा जवाब देखें ।

इसे ऑनलाइन आज़माएं या कई परीक्षण मामलों को सत्यापित करें

व्याख्या

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

परी / जीपी, 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
क्या यह भोली डीएफटी नहीं है? (यानी थीटा (N ^ 2))
मील

1

ऑक्टेव , 109 103 101 100 बाइट्स

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 do my eyes इस रिकर्सिव अकॉर्डिंग लैम्ब्डा से खून बहता है। इसके बड़े हिस्से को @ दोष के जवाब से हटा दिया गया था।

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
)

मुझे समझ नहीं आया कि आपने क्या किया लेकिन मुझे यह बहुत पसंद है।
दोष

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) सभी परीक्षण पास कर सकता है और इस 'प्रतियोगिता' के लिए प्रविष्टि के रूप में ठीक है, तो एक को h () या hlp () थ्रू fft () नीचे तर्कों की जाँच के लिए कॉल करना होगा । मुझे नहीं पता कि यह सॉफ्टवेयर ठीक हो सकता है क्योंकि मैंने केवल वही देखा था जो अन्य ने लिखा था, और जिस तरह से यह संभव कुछ सही परिणाम वापस करने के लिए Axiom में चला सकता है वह खोज। नीचे कुछ टिप्पणियों के साथ अपुष्ट कोड:

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

कुछ में मैंने एच () या एफएफटी () देखा था जो सटीक समाधान लौटाएगा, लेकिन यदि सरलीकरण इसमें अच्छा नहीं है:

(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

एपीएल (एनएआरएस), 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 
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.