上下文
为了更好地理解x射线衍射,我用python语言编写了代码.对于位置为R_i的点的集合,德拜公式为
其中指数中的i是复数,所有其他i是指数,为了简单起见,现在是b_i = b_j = 1
.
Now I tried explicitly calculating this sum for a collection of points of which I have the coordinates
import numpy as np
# set up grid
dims = 2
side = 30
points = np.power(side, dims)
coords = np.zeros((dims, points))
xc, yc = np.meshgrid(np.arange(side), np.arange(side))
coords[0, :] = xc.reshape((points))
coords[1, :] = yc.reshape((points))
# calculate diffraction
xdist = np.subtract.outer(coords[0], coords[0])
ydist = np.subtract.outer(coords[1], coords[1])
rdist = np.stack((xdist, ydist))
rdist = rdist.reshape(2, rdist.shape[1]*rdist.shape[2])
qs = 200
qspace = np.stack((np.linspace(-2, 8, qs), np.zeros(qs)))
diffrac = np.sum(np.exp(-1j * np.tensordot(qspace.T, rdist, axes=1)), axis=1)
几秒钟后我得到了以下信息
这看起来和预期的一样(周期为2 π,因为点的间距为1).这需要一些时间也是有道理的:对于900个点,必须计算810000个距离.我不使用循环,所以我认为代码在效率方面并不差,但我手动计算这个总和的事实似乎固有地慢.
思想
现在看起来,如果我能用一个离散的快速傅立叶变换来实现这个目标——给定和的形状,事情会大大加快.然而:
- 对于离散傅里叶变换,我仍然需要对图像进行像素化(据我所知),以便在我的信号点之间包含大量的空白空间.就像我要转换我分享的第一张图片的像素一样.这似乎也不太有效(例如,因为采样).
- 我想在之后移动点,所以第一个图像是一个网格,因此定期采样的事实并没有特别的帮助.看起来好像非均匀傅立叶变换可以帮助我,但仍然需要我对图像进行"像素化",并将某些值设置为0.
问题
有没有一种方法可以使用FFT(或其他方法)更快地计算和,从np.数组坐标(x,y)的列表开始?(狄拉克德尔塔函数,如果你想...).
特别是相关数学技术/Python函数/Python包的指针将受到赞赏.我对实际应用中使用傅立叶变换并不熟悉,但我在网上找到的大多数material 似乎都无关紧要.所以可能我看错了方向,或者我缺乏理解.所有的帮助是赞赏!
(第一张图片是https://www.ill.eu/fileadmin/user_upload/ILL/6_Careers/1_All_our_vacancies/PhD_recruitment/Student_Seminars/2017/19-2017-05-09_Fischer_Cookies.pdf的截图,因为似乎SO上没有数学符号,或者我没有找到它)