Ayrık Fourier Dönüşümünü hesaplayın


9

Herhangi bir uzunlukta bir dizi için Ayrık Fourier Dönüşümü (DFT) uygulayın. Bu bir işlev veya program olarak uygulanabilir ve dizi bağımsız değişken olarak veya standart girdi kullanılarak verilebilir.

Algoritma, ileri yönde standart DFT'ye dayalı bir sonuç hesaplayacaktır. Giriş dizisi uzunluğa sahiptir Nve oluşur [x(0), x(1), ..., x(N-1)]. Çıktı sekansı aynı uzunluğa sahip olacak ve [X(0), X(1), ..., X(N-1)]her birinin X(k)aşağıdaki ilişki ile tanımlandığı yerden oluşacaktır .

DFT

kurallar

  • Bu böylece en kısa çözüm kazanır.
  • DFT'yi ileri veya geri (ters olarak da bilinir) yönde hesaplayan yapılara izin verilmez.
  • Kayan nokta yanlışlıkları size karşı sayılmaz.

Test Durumları

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]

Yardım

2 gücüne eşit diziler için bir FFT algoritması kullanarak DFT bulmak için daha önce bir zorluk vardı. Burada size yardımcı olabilecek bazı hileler bulabilirsiniz. Bu zorluğun sizi herhangi bir karmaşıklıkla sınırlamadığını ve ayrıca çözümünüzün herhangi bir uzunlukta diziler için çalışmasını gerektirdiğini unutmayın.

Yanıtlar:


2

Jöle , 16 15 bayt

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

Çevrimiçi deneyin!

Nasıl çalışır

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 bayt

lambda x,e=enumerate:[sum(t/1j**(4*k*n/len(x))for n,t in e(x))for k,_ in e(x)]

Ideone üzerinde test edin .

Kod, eşdeğer formülü kullanır

formül


Vay canına, mizahi figürler. Daha kısa kodlara izin verebilecek eşdeğer formülleri görmek güzel.
mil

4

J, 30 20 bayt

Miles sayesinde 3 bayt .

Bunu kullanır e^ipi = -1.

Formül olur X_k = sum(x_n / ((-1)^(2nk/N))).

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

kullanım

>> 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 ve <<STDOUT nerede .

"Kayan nokta yanlışlıkları size karşı sayılmaz."


3

MATL , 20 16 bayt

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

Girdi bir sütun vektörüdür, yani virgülleri noktalı virgülle değiştirin:

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

Bu , exp ( ) = −1 ve MATL'nin tamsayı olmayan üslü güç operatörünün (çoğu programlama dilinde olduğu gibi) ana dal sonucunu ürettiği gerçeklere dayanarak Leaky Nun yanıtında formülü kullanır .

Çevrimiçi deneyin!

Octave'nin karmaşık sayılarla garip aralığı nedeniyle, gerçek ve hayali parçalar, ortaya çıkan vektörün farklı girişleri gibi bir boşlukla ayrılır. Bu çok çirkin görünüyorsa , çıktının her girdisinin farklı bir satırda olmasını sağlamak !için sonuna ( 17 bayt ) bir a ekleyin .

açıklama

-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

Pyth, 30

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

Test odası

Çok saf bir yaklaşım, sadece formülün bir uygulaması. Eklemeli olması gereken değerlerle çeşitli küçük kayan nokta sorunlarıyla karşılaşır ve sıfırın biraz altında olan değerlerle sonuçlanır.

Garip bir şekilde .jargüman olmadan çalışmıyor gibi görünüyor, ancak doğru kullanıp kullanmadığımdan emin değilim.


1
10k için tebrikler !!
Luis Mendo



2

Python 2, 78 bayt

l=input();p=1
for _ in l:print reduce(lambda a,b:a*p+b,l)*p;p*=1j**(4./len(l))

Polinom Her enerji için değerlendirilir parasında 1j**(4./len(l)).

İfade reduce(lambda a,b:a*p+b,l), Horner yöntemi ile ldeğer püzerinde verilen polinomu değerlendirir :

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

Dışında, giriş listesi ters, terim sonunda sabit. Bunu tersine çevirebiliriz, ancak p**len(l)==1Fourier katsayıları için, ptüm sonucu tersine çevirme ve çarpma hackini kullanabiliriz p.

Eşit uzunlukta bazı girişimler:

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)

1 byte daha fazlası için bir fonksiyon olarak (79):

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

Özyineleme girişimi (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)

Yinelemeli simülasyon 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

2

C (gcc) , 86 78 bayt

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

Çevrimiçi deneyin!

Bu, çıkış vektörünün kullanılmadan önce sıfırlandığını varsayar.


1

Python 2, 89 bayt

Bunu kullanır e^ipi = -1.

Formül olur 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))]

Boşver!


Bunu ayrı bir cevap olarak gönderin!
Sızdıran Rahibe

Tamam, eğer öyle diyorsan.
Dennis

1

Mathematica, 49 48 47 bayt

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

@Dennis ' çözeltisinden elde edilen formüle dayanmaktadır .


1

Aksiyom, 81 bayt

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

burada birisinin gönderdiği formülü kullanarak. Sonuçlar

(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

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.