整合一个2D向量场数组(反转np.gradient)

5
我有一个问题: 我想要对一个二维数组进行积分,基本上是对梯度算子进行反转。
假设我的数组非常简单,如下所示:
shape = (60, 60)
sampling = 1
k_mesh = np.meshgrid(np.fft.fftfreq(shape[0], sampling), np.fft.fftfreq(shape[1], sampling))

然后我将我的向量场构建为一个复数值数组(x-向量=实部,y-向量=虚部):
k = k_mesh[0] + 1j * k_mesh[1]

所以,例如实部看起来像这样 enter image description here 现在我计算梯度:
k_grad = np.gradient(k, sampling)

然后我使用傅里叶变换来反转它,使用以下函数:
def freq_array(shape, sampling):

    f_freq_1d_y = np.fft.fftfreq(shape[0], sampling[0])
    f_freq_1d_x = np.fft.fftfreq(shape[1], sampling[1])
    f_freq_mesh = np.meshgrid(f_freq_1d_x, f_freq_1d_y)
    f_freq = np.hypot(f_freq_mesh[0], f_freq_mesh[1])

    return f_freq


def int_2d_fourier(arr, sampling):
    freqs = freq_array(arr.shape, sampling)

    k_sq = np.where(freqs != 0, freqs**2, 0.0001)
    k = np.meshgrid(np.fft.fftfreq(arr.shape[0], sampling), np.fft.fftfreq(arr.shape[1], sampling))

    v_int_x = np.real(np.fft.ifft2((np.fft.fft2(arr[1]) * k[0]) / (2*np.pi * 1j * k_sq)))
    v_int_y = np.real(np.fft.ifft2((np.fft.fft2(arr[0]) * k[0]) / (2*np.pi * 1j * k_sq)))

    v_int_fs = v_int_x + v_int_y
    return v_int_fs


k_int = int_2d_fourier(k, sampling)

很不幸,在k有突变的位置,结果不是非常准确,如下图所示,它显示了kk_int的水平线轮廓。

enter image description here

有什么办法可以提高精度吗?是否有一种方法可以使其完全相同?

它在同一位置穿过0,对吧?这是从白色到黑色的转换处。 - user2261062
如果您的图像是人工制造的,请将其放大,这样您将采样更多的像素,因此您将拥有更多的频率。问题来自于突然变化,除非您拥有无限数量的谐波,否则无法对其进行建模。 - user2261062
当然,我可以对这个进行重新采样,但是对于其他问题,我的采样是固定的。 - F. Win
那么你的答案是这是一个无法解决的人为因素,因为它源于数据的离散采样? - F. Win
你认为使用真实空间积分会更好吗?如果是,你有示例代码吗? - F. Win
显示剩余2条评论
1个回答

1
我实际上找到了一个解决方案。集成本身产生非常准确的结果。 然而,来自numpy的梯度函数计算二阶精确中心差分,这意味着梯度本身已经是一个近似值。
当您使用类似于2D高斯函数的解析公式替换上述问题时,可以通过解析计算导数。当积分此解析派生函数时,误差在10^-10的数量级上(取决于高斯函数的宽度,可能会导致混叠效应)。
长话短说:上面提出的集成函数按预期工作!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接