如何计算场的拉普拉斯?
我正在尝试使用 scipy.ndimage.convolve 来计算一个二维场A的拉普拉斯算子。
stencil = numpy.array([[0, 1, 0],[1, -4, 1], [0, 1, 0]])
scipy.ndimage.convolve(A, stencil, mode='wrap')
不过,这似乎没有给我正确的结果。有没有人知道我哪里出错了,或者在numpy中有没有更好的计算拉普拉斯算子的方法?
4 个回答
1
你试过其他的拉普拉斯卷积核吗,比如 [[1,1,1][1,-8,1][1,1,1]]
?
5
五年前我在想,还有人关心这个吗...
我觉得这是因为卷积方法只是一个近似值,模板基本上是通过有限离散微分来近似二阶导数。增量越小,数值近似就会越接近真实值。
我根据别人的信息做了一些测试。下面是代码和结果图:
import numpy
import scipy.ndimage.filters as filters
import scipy.signal as signal
import matplotlib.pyplot as plt
stencil=numpy.array([[0,1,0],[1,-4,1],[0,1,0]])
fig=plt.figure(figsize=(10,10),dpi=100)
for ii,jj in enumerate([10,100,1000,10000]):
x=numpy.linspace(-5,5,jj)
xx,yy=numpy.meshgrid(x,x)
step=x[1]-x[0]
image=numpy.exp(-xx**2-yy**2)
lap1=filters.laplace(image)/step**2
#lap2=filters.convolve(image,stencil,mode='wrap')/step**2
#lap3=signal.convolve2d(image,stencil,mode='same')/step**2
lap4=4*image*(xx**2+yy**2)-4*image
ax=fig.add_subplot(2,2,ii+1)
img=ax.imshow(lap1-lap4)
ax.set_title('stencil - analytical (dx=%.4f)' %step)
plt.colorbar(img)
fig.tight_layout()
plt.show()
filters.laplace()
、filters.convolve()
和 signal.convolve2d()
的结果都非常接近(实际上,如果你查看 filters.laplace()
的源代码,它实际上和卷积模板核的操作是一样的),所以我只包含了 filters.laplace()
的结果。注意,上述所有操作都没有除以步长的平方。
图表显示,增量步长越小,结果就越接近解析解(也就是 4z(x^2+y^2)-4z
)。
2
我有另一个想法:你有没有考虑过,为了近似拉普拉斯算子,你的模板应该用步长的平方来除,也就是step**2,其中step是你网格的步长?只有这样,你才能把ndimage.convolve的结果和理论结果进行比较。
实际上,使用高斯函数时,我得到的结果表明ndimage.convolve的效果相当不错:
from scipy import ndimage
stencil = numpy.array([[0, 1, 0],[1, -4, 1], [0, 1, 0]])
x = linspace(-10, 10, 100)
y = linspace(-10, 10, 100)
xx, yy = meshgrid(x, y)
image = exp(-xx**2-yy**2) # Standard deviation in x or y: 1/sqrt(2)
laplaced = ndimage.convolve(image, stencil)/(x[1]-x[0])**2 # stencil from original post
expected_result = -4*image + 8*(xx**2+yy**2)*image # Very close to laplaced, in most points!