在 Cython 中为周期性边界条件实现二维拉普拉斯算子
Implementing 2D Laplacian in Cython for periodic boundary counditions
我有一个实现二维拉普拉斯算子的代码 finite differences integration method for partial differential equations, using the roll method of Numpy :
def lapOp(u):
"""
This is the laplacian operator on 2D array
of stencil of 4th accuracy terms
"""
lap = ((4.0/3.0)*np.roll(u,1,axis=0) + (4.0/3.0)*np.roll(u,-1,axis=0) + (4.0/3.0)*np.roll(u,1,axis=1) + (4.0/3.0)*np.roll(u,-1,axis=1) -5.0*u)
lap -= ((1.0/12.0)*np.roll(u,2,axis=0) + (1.0/12.0)*np.roll(u,-2,axis=0) + (1.0/12.0)*np.roll(u,2,axis=1) + (1.0/12.0)*np.roll(u,-2,axis=1))
lap = lap / hh
return lap
我想对我的代码进行 cythonize - roll 方法可以在我的 pyx 代码中工作还是我应该使用 C 实现 roll 方法?
简短的回答是:roll
可以在 Cython 中使用,但不会快很多(任何?)。
如果你想要速度,你应该避免完全使用 roll
之类的东西(它很慢,因为它每次调用时都会创建一个完整的副本),而是使用索引来获取 numpy 数组的大块视图u
。您不需要 Cython,也可能不会从中受益。
下面是一个不完整的例子(足以说明要点):
def lapOp(u):
lap = np.empty_like(u)
# this bit is equivalent to (4.0/3)*np.roll(u,1,axis=0)
lap[1:,:] = (4.0/3.0)*u[:-1,:]
lap[0,:] = (4.0/3.0)*u[-1,:]
# add (4.0/3)*np.roll(u,-1,axis=0)
lap[:-1,:] += (4.0/3.0)*u[1:,:]
lap[-1,:] += (4.0/3.0)*u[0,:]
# add (4.0/3)*np.roll(u,1,axis=1)
lap[:,1:] += (4.0/3.0)*u[:,:-1]
lap[:,0] += (4.0/3.0)*u[:,-1]
# the remainder is left as a rather tedious exercise for the reader
return lap/hh
我有一个实现二维拉普拉斯算子的代码 finite differences integration method for partial differential equations, using the roll method of Numpy :
def lapOp(u):
"""
This is the laplacian operator on 2D array
of stencil of 4th accuracy terms
"""
lap = ((4.0/3.0)*np.roll(u,1,axis=0) + (4.0/3.0)*np.roll(u,-1,axis=0) + (4.0/3.0)*np.roll(u,1,axis=1) + (4.0/3.0)*np.roll(u,-1,axis=1) -5.0*u)
lap -= ((1.0/12.0)*np.roll(u,2,axis=0) + (1.0/12.0)*np.roll(u,-2,axis=0) + (1.0/12.0)*np.roll(u,2,axis=1) + (1.0/12.0)*np.roll(u,-2,axis=1))
lap = lap / hh
return lap
我想对我的代码进行 cythonize - roll 方法可以在我的 pyx 代码中工作还是我应该使用 C 实现 roll 方法?
简短的回答是:roll
可以在 Cython 中使用,但不会快很多(任何?)。
如果你想要速度,你应该避免完全使用 roll
之类的东西(它很慢,因为它每次调用时都会创建一个完整的副本),而是使用索引来获取 numpy 数组的大块视图u
。您不需要 Cython,也可能不会从中受益。
下面是一个不完整的例子(足以说明要点):
def lapOp(u):
lap = np.empty_like(u)
# this bit is equivalent to (4.0/3)*np.roll(u,1,axis=0)
lap[1:,:] = (4.0/3.0)*u[:-1,:]
lap[0,:] = (4.0/3.0)*u[-1,:]
# add (4.0/3)*np.roll(u,-1,axis=0)
lap[:-1,:] += (4.0/3.0)*u[1:,:]
lap[-1,:] += (4.0/3.0)*u[0,:]
# add (4.0/3)*np.roll(u,1,axis=1)
lap[:,1:] += (4.0/3.0)*u[:,:-1]
lap[:,0] += (4.0/3.0)*u[:,-1]
# the remainder is left as a rather tedious exercise for the reader
return lap/hh