Матрица DFT в python

Какой самый простой способ получить матрицу DFT для двухмерного DFT в python? Я не мог найти такую ​​функцию в numpy.fft. Спасибо!

Ответ 1

Я не думаю, что это встроено. Однако, прямой расчет прост:

import numpy as np
def DFT_matrix(N):
    i, j = np.meshgrid(np.arange(N), np.arange(N))
    omega = np.exp( - 2 * pi * 1J / N )
    W = np.power( omega, i * j ) / sqrt(N)
    return W

РЕДАКТИРОВАТЬ Для 2D БПФ матрицы, вы можете использовать следующее:

x = np.zeros(N, N) # x is any input data with those dimensions
W = DFT_matrix(N)
dft_of_x = W.dot(x).dot(W)

Ответ 2

Самый простой и, скорее всего, самый быстрый способ - использовать fft из SciPy.

import scipy as sp

def dftmtx(N):
    return sp.fft(sp.eye(N))

Если вы знаете еще более быстрый способ (может быть, более сложный), я был бы признателен за ваш вклад.

Чтобы сделать его более актуальным для основного вопроса - вы также можете сделать это с помощью numpy:

import numpy as np

dftmtx = np.fft.fft(np.eye(N))

Когда я сравнивал оба из них, у меня было впечатление, что scipy был немного быстрее, но я не сделали это тщательно, и это было когда-то так, поэтому не верьте мне на слово.

Здесь довольно хороший источник для реализаций FFT в python: http://nbviewer.ipython.org/url/jakevdp.github.io/downloads/notebooks/UnderstandingTheFFT.ipynb Это скорее с точки зрения скорости, но в этом случае мы действительно можем видеть, что иногда это происходит и с простотой.

Ответ 3

@Alex | в основном корректно, я добавляю здесь версию, которую я использовал для 2-D DFT:

def DFT_matrix_2d(N):
    i, j = np.meshgrid(np.arange(N), np.arange(N))
    A=np.multiply.outer(i.flatten(), i.flatten())
    B=np.multiply.outer(j.flatten(), j.flatten())
    omega = np.exp(-2*np.pi*1J/N)
    W = np.power(omega, A+B)/N
    return W

Ответ 4

Лямбда-функции тоже работают:

dftmtx = lambda N: np.fft.fft(np.eye(N))

Вы можете вызвать его, используя dftmtx (N). Пример:

In [62]: dftmtx(2)
Out[62]: 
array([[ 1.+0.j,  1.+0.j],
       [ 1.+0.j, -1.+0.j]])

Ответ 5

С scipy 0.14 имеется встроенный scipy.linalg.dft:

Пример с 16-точечной матрицей DFT:

>>> import scipy.linalg
>>> import numpy as np
>>> m = scipy.linalg.dft(16)

Подтвердить унитарное свойство, матрица заметок не масштабируется, поэтому 16*np.eye(16):

>>> np.allclose(np.abs(np.dot( m.conj().T, m )), 16*np.eye(16))
True

Для 2D DFT-матрицы это просто проблема тензорного продукта или, особенно, Kronecker Product в этом случае, поскольку мы имеем дело с матричной алгеброй.

>>> m2 = np.kron(m, m) # 256x256 matrix, flattened from (16,16,16,16) tensor

Теперь мы можем дать ему черепичную визуализацию, сделав перестановку каждой строки в квадратный блок

>>> import matplotlib.pyplot as plt
>>> m2tiled = m2.reshape((16,)*4).transpose(0,2,1,3).reshape((256,256))
>>> plt.subplot(121)
>>> plt.imshow(np.real(m2tiled), cmap='gray', interpolation='nearest')
>>> plt.subplot(122)
>>> plt.imshow(np.imag(m2tiled), cmap='gray', interpolation='nearest')
>>> plt.show()

Результат (реальная и мнимая часть отдельно):

Основание 2D DFT

Как вы можете видеть, это базовые функции 2D DFT

Ссылка в документацию