Apply DFT matrix along each axis of 3D array in NumPy?

江枫思渺然 提交于 2021-02-07 09:24:24

问题


I can first obtain the DFT matrix of a given size, say n by

import numpy as np
n = 64
D = np.fft.fft(np.eye(n))

The FFT is of course just a quick algorithm for applying D to a vector:

x = np.random.randn(n)
ft1 = np.dot(D,x)
print( np.abs(ft1 - fft.fft(x)).max() )
# prints near double precision roundoff

The 2D FFT can be obtained by applying D to both the rows and columns of a matrix:

x = np.random.randn(n,n)
ft2 = np.dot(x, D.T) # Apply D to rows.
ft2 = np.dot(D, ft2) # Apply D to cols.
print( np.abs(ft2 - fft.fft2(x)).max() )
# near machine round off again

How do I compute this analogously for the 3 dimensional Discrete Fourier Transform?

I.e.,

x = np.random.randn(n,n,n)
ft3 = # dot operations using D and x
print( np.abs(ft3 - fft.fftn(x)).max() )
# prints near zero

Essentially, I think I need to apply D to each column vector in the volume, then each row vector in the volume, and finally each "depth vector". But I'm not sure how to do this using dot.


回答1:


You can use the einsum expression to perform the transformation on each index:

x = np.random.randn(n, n, n)
ft3 = np.einsum('ijk,im->mjk', x, D)
ft3 = np.einsum('ijk,jm->imk', ft3, D)
ft3 = np.einsum('ijk,km->ijm', ft3, D)
print(np.abs(ft3 - np.fft.fftn(x)).max())
1.25571216554e-12

This can also be written as a single NumPy step:

ft3 = np.einsum('ijk,im,jn,kl->mnl', ft3, D, D, D, optimize=True)

Without the optimize argument (available in NumPy 1.12+) it will be very slow however. You can also do each of the steps using dot, but it requires a bit of reshaping and transposing. In NumPy 1.14+ the einsum function will automatically detect the BLAS operations and do this for you.



来源:https://stackoverflow.com/questions/48290758/apply-dft-matrix-along-each-axis-of-3d-array-in-numpy

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!