Python 计算三维旋度的最快算法
我想写一段代码,用周期性边界条件计算向量场的旋度到二阶。然而,我做的算法非常慢,我想知道是否有人知道任何替代算法 给出更具体的上下文:我使用一个3xAxBxC numpy数组作为向量场,其中第一个轴表示笛卡尔方向x,y,z,a,B,C表示笛卡尔方向上的箱子数量,即分辨率。例如,我可能有一个向量场F=np.zeros3,64,64,64,其中Fx=F[0]本身就是一个64x64x64笛卡尔晶格。到目前为止,我的解决方案是使用以3点为中心的差分模板来计算导数,并使用嵌套循环来迭代所有不同的维度,使用模运算来强制执行周期性边界条件,例如,见下文。然而,当我的分辨率增加A,B,C的大小时,这开始需要很长的时间,最多2分钟,如果我在模拟中这样做几百次,这就加起来了——这只是更大算法的一小部分。我想知道是否有人知道这样做的替代方法 将numpy作为np导入 F=np.array[np.one[128128],2*np.one[128128], 3*np.ones[128128]] VxF=np.数组[np.零[128128],np.零[128128], np.零[128128]] 对于范围0128中的i: 对于范围0128中的j: 对于范围0128中的k: VxF[0][i,j,k]=0.5*F[2][i,j+1%128,k]- F[2][i,j-1,k]-F[1][i,j,k+1%128]-F[1][i,j,k-1] VxF[1][i,j,k]=0.5*F[0][i,j,k+1%128]- F[0][i,j,k-1]-F[2][i+1%128,j,k]-F[2][i-1,j,k] VxF[2][i,j,k]=0.5*F[1][i+1%128,j,k]- F[1][i-1,j,k]-F[0][i,j+1%128,k]-F[0][i,j-1,k]Python 计算三维旋度的最快算法,python,algorithm,physics,numerical-methods,numerical-computing,Python,Algorithm,Physics,Numerical Methods,Numerical Computing,我想写一段代码,用周期性边界条件计算向量场的旋度到二阶。然而,我做的算法非常慢,我想知道是否有人知道任何替代算法 给出更具体的上下文:我使用一个3xAxBxC numpy数组作为向量场,其中第一个轴表示笛卡尔方向x,y,z,a,B,C表示笛卡尔方向上的箱子数量,即分辨率。例如,我可能有一个向量场F=np.zeros3,64,64,64,其中Fx=F[0]本身就是一个64x64x64笛卡尔晶格。到目前为止,我的解决方案是使用以3点为中心的差分模板来计算导数,并使用嵌套循环来迭代所有不同的维度,使用
为了再次迭代,我正在寻找一种算法,在给定周期边界条件的情况下,计算向量场数组的旋度到二阶,比我现在的算法要快。也许没有什么可以做到这一点,但我只是想在我继续运行这个算法之前检查一下。感谢你们每个人都提前准备好了 可能有更好的工具来实现这一点,但这里有一个使用numba的200倍加速:
纯Python版本在我的机器上需要13秒,而numba版本需要65毫秒。WOW!这真是太神奇了。非常感谢你!当我今天早上开始工作时,我运行了完整的算法,耗时约1小时。我刚刚添加了找你的零钱,只花了约2分钟。我将把这个问题留一段时间,看看是否还有其他算法可以供我自己学习,但这确实解决了我的问题。再次感谢你!不用担心,numba是一个很棒的工具,当你有一堆嵌套的循环,里面有简单的数学时,它非常有用。请注意fastmath选项会破坏IEEE 754的合规性,并且不会检查Inf和NaN。这对你来说可能很好,但在计算导数时似乎有点危险。
import numpy as np
from numba import jit
def pure_python():
F =np.array([np.ones([128,128,128]),2*np.ones([128,128,128]),
3*np.ones([128,128,128])])
VxF =np.array([np.zeros([128,128,128]),np.zeros([128,128,128]),
np.zeros([128,128,128])])
for i in range(0,128):
for j in range(0,128):
for k in range(0,128):
VxF[0][i,j,k] = 0.5*((F[2][i,(j+1)%128,k]-
F[2][i,j-1,k])-(F[1][i,j,(k+1)%128]-F[1][i,j,k-1]))
VxF[1][i,j,k] = 0.5*((F[0][i,j,(k+1)%128]-
F[0][i,j,k-1])-(F[2][(i+1)%128,j,k]-F[2][i-1,j,k]))
VxF[2][i,j,k] = 0.5*((F[1][(i+1)%128,j,k]-
F[1][i-1,j,k])-(F[0][i,(j+1)%128,k]-F[0][i,j-1,k]))
return VxF
@jit(fastmath=True)
def with_numba():
F =np.array([np.ones([128,128,128]),2*np.ones([128,128,128]),
3*np.ones([128,128,128])])
VxF =np.array([np.zeros([128,128,128]),np.zeros([128,128,128]),
np.zeros([128,128,128])])
for i in range(0,128):
for j in range(0,128):
for k in range(0,128):
VxF[0][i,j,k] = 0.5*((F[2][i,(j+1)%128,k]-
F[2][i,j-1,k])-(F[1][i,j,(k+1)%128]-F[1][i,j,k-1]))
VxF[1][i,j,k] = 0.5*((F[0][i,j,(k+1)%128]-
F[0][i,j,k-1])-(F[2][(i+1)%128,j,k]-F[2][i-1,j,k]))
VxF[2][i,j,k] = 0.5*((F[1][(i+1)%128,j,k]-
F[1][i-1,j,k])-(F[0][i,(j+1)%128,k]-F[0][i,j-1,k]))
return VxF