Обчисли дискретні перетворення Фур'є


9

Реалізуйте дискретні перетворення Фур'є (DFT) для послідовності будь-якої довжини. Це може бути реалізовано як функція або програма, і послідовність може бути задана як аргумент, або за допомогою стандартного введення.

Алгоритм обчислює результат на основі стандартного DFT у прямому напрямку. Послідовність введення має довжину Nі складається з [x(0), x(1), ..., x(N-1)]. Вихідна послідовність матиме однакову довжину і складається з того, [X(0), X(1), ..., X(N-1)]де кожен X(k)визначається співвідношенням нижче.

DFT

Правила

  • Це є тому виграє найкоротше рішення.
  • Вбудовані, які обчислюють DFT вперед або назад (також відомий як зворотний) напрямків, не дозволяються.
  • Неточності з плаваючою комою не будуть зараховані проти вас.

Випробування

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]

Довідка

Був попередній виклик пошуку DFT за допомогою алгоритму FFT для послідовностей довжиною, рівній потужності 2. Ви можете знайти деякі хитрощі, які можуть вам допомогти тут. Майте на увазі, що ця проблема не обмежує вас ніякою складністю, а також вимагає, щоб ваше рішення працювало на послідовності будь-якої довжини.

Відповіді:


2

Желе , 16 15 байт

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

Спробуйте в Інтернеті!

Як це працює

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 байт

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

Перевірте це на Ideone .

У коді використовується еквівалентна формула

формула


Нічого собі, жартівливі фігури. Приємно бачити еквівалентні формули, які дозволяють скоротити код.
миль

4

J, 30 20 байт

3 байти завдяки @miles .

Використовує той факт, що e^ipi = -1.

Формула стає X_k = sum(x_n / ((-1)^(2nk/N))).

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

Використання

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

"Неточності з плаваючою комою проти вас не зараховуються."


3

MATL , 20 16 байт

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

Введення - вектор стовпця, тобто замініть коми на крапки з комою:

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

Для цього використовується формула у відповіді Leaky Nun , заснована на фактах, що exp ( ) = −1, і що силовий оперант MATL з нецілим показником виробляє (як у більшості мов програмування) результат головної гілки .

Спробуйте в Інтернеті!

Через дивний проміжок Октава зі складними числами реальна і уявна частини розділені пробілом, як і різні записи результуючого вектора. Якщо це виглядає занадто некрасиво, додайте в !кінці ( 17 байт ), щоб кожен запис результату був у іншому рядку.

Пояснення

-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

Піт, 30

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

Тестовий сюїт

Дуже наївний підхід, просто реалізація формули. Враховує різні мінорні проблеми з плаваючою точкою зі значеннями, які повинні бути додатковою інверсією, додаючи, щоб у результаті вийшло значення, яке трохи не дорівнює нулю.

Як .jне дивно, це не працює без аргументів, але я не впевнений, чи правильно я його використовую.


1
З повагою 10 к !!
Луїс Мендо



2

Python 2, 78 байт

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

Поліном обчислюється для кожної потужності pз 1j**(4./len(l)).

Вираз reduce(lambda a,b:a*p+b,l)оцінює поліном, заданий lзначенням pза методом Горнера:

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

За винятком того, що список вихідних даних є зворотним, з постійним терміном в кінці. Ми могли б це змінити, але оскільки p**len(l)==1для коефіцієнтів Фур'є ми можемо використовувати хак інвертування pта множення всього результату на p.

Деякі спроби однакової довжини:

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 байт більше (79):

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

Спроба рекурсії (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)

Ітераційне моделювання 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 байт

Використовує той факт, що e^ipi = -1.

Формула стає 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))]

Ідей це!


Опублікуйте це як окрему відповідь!
Leaky Nun

Добре, якщо ти так кажеш.
Денніс


1

Аксіома, 81 байт

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

використовуючи формулу, яку хтось публікує тут. Результати

(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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.