我必须以数值方式计算高斯函数的二阶导数:
我在这里阅读了有关该主题的每个问题,但无法得出好的结果。我选择 NumPy 作为我的首选工具。
我们教授的指示:
x大小的数组。所以,。计算N = 128dx = 1-64, -63, ..., 62, 63f(x)f(x)并接收变换后的数组f_m。f_m1/n(但这是现在最小的问题)现在这是我的代码,尽可能简单。
import numpy as np
# Set some parameters
n = 128
dx = 1
a = 0.001
# Create x, calculate f(x) and its FFT
x = np.arange(-n/2, n/2) * dx
psi = np.exp(-a * x * x)
f_m = np.fft.fft(psi)
# k_m creation according to professor (point 3. in my instruction)
k_m = np.arange(-n/2, n/2, dtype=float)
k_m[:int(n / 2)] = (2 * np.pi * k_m[:int(n / 2)]) / (n * dx)
k_m[int(n / 2):] = (2 * np.pi * (k_m[int(n / 2):] - n)) / (n * dx)
# Multiply f_m by (j * k_m)^q. For q=2, this is -k_m^2
f_m *= -k_m * k_m
# Inverse FFT on the result to get the second derivative and scale by 1 / n
f_m = np.fft.ifft(f_m) / n
Run Code Online (Sandbox Code Playgroud)
我无法得到的一件事是结果仍然有虚部,所以有些东西是不对的。有人可以帮忙吗?
编辑:克里斯·卢恩戈的答案有效。
这部分是错误的:
k_m = np.arange(-n/2, n/2, dtype=float)
Run Code Online (Sandbox Code Playgroud)
步骤 3 中的说明讨论m从 0 到n-1。代码应该如下所示:
k_m = np.arange(-n/2, n/2, dtype=float)
Run Code Online (Sandbox Code Playgroud)
FFT 产生一个输出,其中第一个元素(索引 0)是 0 频率,而不是 频率-n/2。
k_m如果您使用fftshift将 0 频率仓移动到数组的中间,则当前版本的数组可能是正确的,尽管我不完全确定这一点(也许-n后半部分应该被删除?)。
n最后,这里不需要除法:
f_m = np.fft.ifft(f_m) / n
Run Code Online (Sandbox Code Playgroud)
NumPy IFFT 已经标准化。
并记住f_m.real在验证虚部几乎为零后绘制 (这些值应仅由于数字舍入误差而与零不同)。
例如,如果您做得a更大一点,a=0.005那么您的输入高斯完全适合输入信号,并且您不会因过滤被切断的信号而产生丑陋的边缘效应。