【问题标题】:Discrete Laplacian (del2 equivalent) in PythonPython中的离散拉普拉斯算子(del2等效)
【发布时间】:2011-01-14 14:41:05
【问题描述】:

我需要 Python / Numpy 等效的 Matlab(八度)离散拉普拉斯算子(函数)del2()。我尝试了几个 Python 解决方案,但似乎没有一个与 del2 的输出相匹配。在八度我有

image = [3 4 6 7; 8 9 10 11; 12 13 14 15;16 17 18 19]
del2(image)

这给出了结果

   0.25000  -0.25000  -0.25000  -0.75000
  -0.25000  -0.25000   0.00000   0.00000
   0.00000   0.00000   0.00000   0.00000
   0.25000   0.25000   0.00000   0.00000

在 Python 上我试过了

import numpy as np
from scipy import ndimage
import scipy.ndimage.filters

image =  np.array([[3, 4, 6, 7],[8, 9, 10, 11],[12, 13, 14, 15],[16, 17, 18, 19]])
stencil = np.array([[0, 1, 0],[1, -4, 1], [0, 1, 0]])
print ndimage.convolve(image, stencil, mode='wrap')

给出结果

[[ 23  19  15  11]
 [  3  -1   0  -4]
 [  4   0   0  -4]
 [-13 -17 -16 -20]]

我也试过了

scipy.ndimage.filters.laplace(image)

这给出了结果

[[ 6  6  3  3]
 [ 0 -1  0 -1]
 [ 1  0  0 -1]
 [-3 -4 -4 -5]]

所以没有一个输出似乎相互匹配。八度代码 del2.m 表明它是一个拉普拉斯算子。我错过了什么吗?

【问题讨论】:

标签: python numpy scipy scientific-computing


【解决方案1】:

也许你正在寻找scipy.ndimage.filters.laplace()

【讨论】:

  • 我测试了这个函数,和del2的输出对比,是不一样的。
  • 当然,离散化可能存在差异,例如边界。您能否更具体地说明您是如何测试它的以及它有何不同?
  • 我测试了 a = [3 4 6;7 8 9;1 3 3];显示(del2(a))。在 Python 端,我调用了你提到的函数,结果完全不同,在每个单元格上。
  • 啊,我测试了一个更大的矩阵,是的,差异在边界上。我怎样才能让边界与 del2 一样?
  • 奇怪的是,在移植 del2 之后,我发现问题出在其他地方,修复了这些问题,结果发现 laplace() 调用也适用于我的应用程序。
【解决方案2】:

您可以使用 convolve 通过将数组与适当的stencil 进行卷积来计算拉普拉斯算子:

from scipy.ndimage import convolve
stencil= (1.0/(12.0*dL*dL))*np.array(
        [[0,0,-1,0,0], 
         [0,0,16,0,0], 
         [-1,16,-60,16,-1], 
         [0,0,16,0,0], 
         [0,0,-1,0,0]])
convolve(e2, stencil, mode='wrap')

【讨论】:

  • e2 是输入数组(2D)的名称吗?是网格点之间的 dL 间距吗?
【解决方案3】:

根据这里的代码

http://cns.bu.edu/~tanc/pub/matlab_octave_compliance/datafun/del2.m

我试图编写一个 Python 等价物。它似乎工作,任何反馈将不胜感激。

import numpy as np

def del2(M):
    dx = 1
    dy = 1
    rows, cols = M.shape
    dx = dx * np.ones ((1, cols - 1))
    dy = dy * np.ones ((rows-1, 1))

    mr, mc = M.shape
    D = np.zeros ((mr, mc))

    if (mr >= 3):
        ## x direction
        ## left and right boundary
        D[:, 0] = (M[:, 0] - 2 * M[:, 1] + M[:, 2]) / (dx[:,0] * dx[:,1])
        D[:, mc-1] = (M[:, mc - 3] - 2 * M[:, mc - 2] + M[:, mc-1]) \
            / (dx[:,mc - 3] * dx[:,mc - 2])

        ## interior points
        tmp1 = D[:, 1:mc - 1] 
        tmp2 = (M[:, 2:mc] - 2 * M[:, 1:mc - 1] + M[:, 0:mc - 2])
        tmp3 = np.kron (dx[:,0:mc -2] * dx[:,1:mc - 1], np.ones ((mr, 1)))
        D[:, 1:mc - 1] = tmp1 + tmp2 / tmp3

    if (mr >= 3):
        ## y direction
        ## top and bottom boundary
        D[0, :] = D[0,:]  + \
            (M[0, :] - 2 * M[1, :] + M[2, :] ) / (dy[0,:] * dy[1,:])

        D[mr-1, :] = D[mr-1, :] \
            + (M[mr-3,:] - 2 * M[mr-2, :] + M[mr-1, :]) \
            / (dy[mr-3,:] * dx[:,mr-2])

        ## interior points
        tmp1 = D[1:mr-1, :] 
        tmp2 = (M[2:mr, :] - 2 * M[1:mr - 1, :] + M[0:mr-2, :])
        tmp3 = np.kron (dy[0:mr-2,:] * dy[1:mr-1,:], np.ones ((1, mc)))
        D[1:mr-1, :] = tmp1 + tmp2 / tmp3

    return D / 4

【讨论】:

  • 我猜第一个 if 子句应该是 mc >= 3。另外我不确定它在dx != 1 or dy != 1 时是否返回正确的值
【解决方案4】:
# Laplacian operator (2nd order cetral-finite differences)
# dx, dy: sampling, w: 2D numpy array

def laplacian(dx, dy, w):
    """ Calculate the laplacian of the array w=[] """
    laplacian_xy = np.zeros(w.shape)
    for y in range(w.shape[1]-1):
        laplacian_xy[:, y] = (1/dy)**2 * ( w[:, y+1] - 2*w[:, y] + w[:, y-1] )
    for x in range(w.shape[0]-1):
        laplacian_xy[x, :] = laplacian_xy[x, :] + (1/dx)**2 * ( w[x+1,:] - 2*w[x,:] + w[x-1,:] )
    return laplacian_xy

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-29
    • 2014-04-26
    相关资源
    最近更新 更多