Python 使用numpy改进MonteCarlo模拟的运行时

Python 使用numpy改进MonteCarlo模拟的运行时,python,numpy,runtime,montecarlo,Python,Numpy,Runtime,Montecarlo,我在二维伊辛模型上进行蒙特卡罗模拟已经有一段时间了。我的问题纯粹是计算性的,不需要任何关于伊辛模型的知识 我已经能够完全实现该模型。但是,由于我想模拟相当大的系统,代码运行的速度不够快。运行适当数量的蒙特卡罗扫描,使用我尝试过的最大系统,运行时间大约为半小时 高运行时间的主要原因是我无法保持函数以“numpy形式”运行,我必须使用普通的Python for循环,对我来说,这似乎是最大的问题。我需要帮助的两个功能如下 def helix(S, i, N, L, beta, r, B = 0, J_

我在二维伊辛模型上进行蒙特卡罗模拟已经有一段时间了。我的问题纯粹是计算性的,不需要任何关于伊辛模型的知识

我已经能够完全实现该模型。但是,由于我想模拟相当大的系统,代码运行的速度不够快。运行适当数量的蒙特卡罗扫描,使用我尝试过的最大系统,运行时间大约为半小时

高运行时间的主要原因是我无法保持函数以“numpy形式”运行,我必须使用普通的Python for循环,对我来说,这似乎是最大的问题。我需要帮助的两个功能如下

def helix(S, i, N, L, beta, r, B = 0, J_v = 1, J_p = 1):
    nn = i + 1
    if nn >= N:
        nn -= N
    sum_nn = S[nn]
    nn = i - 1
    if nn < 0:
        nn += N
    sum_nn += S[nn]
    nn = i + L
    if nn >= N:
        nn -= N
    sum_nn += S[nn]
    nn = i - L
    if nn < 0:
        nn += N
    sum_nn += S[nn]
    del_E = 2 * S[i] * sum_nn
    if del_E <= 0:
        S[i] = - S[i]
        return del_E, 2 * S[i] / N
    elif np.exp(-beta * sum_nn) > r:
        S[i] = - S[i]
        return del_E, 2 * S[i] / N
    else:
        return 0, 0


def random_sweep(S, N, L, beta, B = 0, J_v = 1, J_p = 1):
    del_m_sweep = 0
    del_He_sweep = 0
    rand_list_index = np.random.randint(N, size=N)
    rand_numbers = np.random.rand(N)
    for i in range(N):
        del_E, del_m = helix(S, rand_list_index[i], N, L, beta, 
                              rand_numbers[i], B, J_v, J_p)
        del_He_sweep += del_E
        del_m_sweep += del_m
    return del_He_sweep, del_m_sweep
def螺旋(S,i,N,L,beta,r,B=0,J_v=1,J_p=1):
nn=i+1
如果nn>=N:
nn-=N
sum_nn=S[nn]
nn=i-1
如果nn<0:
nn+=N
和=S[nn]
nn=i+L
如果nn>=N:
nn-=N
和=S[nn]
nn=i-L
如果nn<0:
nn+=N
和=S[nn]
del_E=2*S[i]*sum\u nn
如果删除:
S[i]=-S[i]
返回del_E,2*S[i]/N
其他:
返回0,0
def随机扫描(S,N,L,β,B=0,J_v=1,J_p=1):
del_m_扫掠=0
del_He_sweep=0
rand\u list\u index=np.random.randint(N,size=N)
随机数=np.random.rand(N)
对于范围(N)中的i:
del_E,del_m=螺旋线(S,rand_list_index[i],N,L,beta,
随机数[i],B,J_v,J_p)
del_He_sweep+=del_E
del_m_扫掠+=del_m
返回del_He_sweep,del_m_sweep
我想把一切都保持在numpy形式,因为我的理解是,这将极大地提高计算速度。基本上,我想通过调用函数来替换随机_扫描中的for循环
helix(S,rand\u list\u index,N,L,beta,rand\u number,B,J\u v,J\u p)
,并使用numpy灵活性,它将自动调用helix函数
N
次(基于参数
rand\u list\u index
rand\u number
,而不是
rand\u list\u index[i]/code>)。我现在不能这样做的原因是我必须更新索引
I
处的
S
-数组。有办法解决这个问题吗


我已经尝试实现这一点很长一段时间了,所以我真的非常感谢任何帮助

为什么不用C或F编写代码,包装它并从python调用函数?这不是一件很有挑战性的事情,也是一件很有用的事情。但也许你只是想利用numpy中的矢量化——我相信其他人会在这方面帮助你……同样,Ising模型从来都不是我喜欢的东西,但你有没有看过其他人是如何做到的?还有:你有没有分析过你的代码来检查这是你需要优化的?你也可以发布方程式吗?模拟中使用的方程式,从所有实际目的来看,与你给我的链接中的方程式相同。我只在模拟开始时计算总能量和磁化强度,然后我只计算由于单翻转自旋(delu E和delu m)引起的能量和磁化强度的变化。我一定会尝试使用F或C,如果这不能在numpy中完成,谢谢你的提示!我只是想探索将代码的所有部分都保留在python中的可能性,因为这样会更加方便。为什么不用C或F编写代码,包装它,然后从python调用函数?这不是一件很有挑战性的事情,也是一件很有用的事情。但也许你只是想利用numpy中的矢量化——我相信其他人会在这方面帮助你……同样,Ising模型从来都不是我喜欢的东西,但你有没有看过其他人是如何做到的?还有:你有没有分析过你的代码来检查这是你需要优化的?你也可以发布方程式吗?模拟中使用的方程式,从所有实际目的来看,与你给我的链接中的方程式相同。我只在模拟开始时计算总能量和磁化强度,然后我只计算由于单翻转自旋(delu E和delu m)引起的能量和磁化强度的变化。我一定会尝试使用F或C,如果这不能在numpy中完成,谢谢你的提示!我只想探索将代码的所有部分都保留在python中的可能性,因为这样会更加方便