Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 计算三维旋度的最快算法_Python_Algorithm_Physics_Numerical Methods_Numerical Computing - Fatal编程技术网

Python 计算三维旋度的最快算法

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点为中心的差分模板来计算导数,并使用嵌套循环来迭代所有不同的维度,使用

我想写一段代码,用周期性边界条件计算向量场的旋度到二阶。然而,我做的算法非常慢,我想知道是否有人知道任何替代算法

给出更具体的上下文:我使用一个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]
为了再次迭代,我正在寻找一种算法,在给定周期边界条件的情况下,计算向量场数组的旋度到二阶,比我现在的算法要快。也许没有什么可以做到这一点,但我只是想在我继续运行这个算法之前检查一下。感谢你们每个人都提前准备好了

可能有更好的工具来实现这一点,但这里有一个使用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