如何使用 numpy 执行此复制操作?

How to perform this copying operation using numpy?

我一直在为 "diffusion monte carlo" 进行基本模拟,以找到氢分子的基态能量。算法的一个关键部分正在痛苦地减慢我的代码速度,我不确定如何修复它。

这就是代码的作用。我有一个名为 x 的 6 乘 N numpy 数组。该数组表示 N 随机 "walkers",它对 6 维相位 space 进行采样(两个电子乘以 3 维是 6 维)。我建议对每个 "walker" 进行某些随机更改以获得我的新 "walker",然后使用公式为每个新助行器吐出一个数字 "m"。

数m可以是0、1、2、3,这就是难点所在,如果m为0,则将其对应的"walker"从数组中删除。如果 m 为 1,则步行者将保留。如果 m 为 2,则 walker 将保留并且我必须在数组中制作 walker 的新副本。如果 m 是 3,那么 walker 仍然存在,我必须在数组中制作两个新的 walker 副本。在此之后代码重复;对我的步行者阵列等提出了随机更改。

所以;以下是减慢算法速度的代码。这是最后一部分的代码,我必须通过我的 m 并确定如何处理每个 "walker",并创建我的新数组 x 以用于算法的下一次迭代。

        j1 = 0
        n1 = len(x[0,:])
        x_n = np.ones((6,2*n1))
        for i in range(0,n1):
            if m[i] == 1:
                x_n[:,j1] = x[:,i]
                j1 = j1 + 1
            if m[i] == 2:
                x_n[:,j1] = x[:,i]
                x_n[:,j1+1] = x[:,i]
                j1 = j1 + 2
            if m[i] == 3:
                x_n[:,j1] = x[:,i]
                x_n[:,j1+1] = x[:,i]
                j1 = j1 + 3
        x = np.ones((6,j1))
        for j in range(0,j1):
            x[:,j] = x_n[:,j]

我的问题如下;有没有办法使用 numpy 本身来完成我在这段代码中所做的事情?根据我的经验,Numpy 往往比 for 循环快得多。在变分 monte carlo 模拟中直接使用 numpy 我能够在 运行 时间内实现 100 倍的改进。如果你想要完整的代码来实际 运行 算法,那么我可以 post 那个;就是比较长。

令 M 为每个随机游走者的 m 个值的 N x 1 数组。

设 X 为原始 6 x N 数据数组

# np.where returns a list of indices where the condition is satisfied 
zeros =  np.where(M == 0) # don't actually need this variable, I just did it for completeness
ones =   np.where(M == 1)
twos =   np.where(M == 2)
threes = np.where(M == 3)

# use the lists of indices to access the relevant portions of X
ones_array = X[:,ones]
twos_array = X[:,twos]
threes_array = X[:,threes]

# update X with one copy where m = 1, two copies where m = 2, three copies where m = 3
X = np.concatenate((ones_array,twos_array,twos_array,threes_array,threes_array,threes_array),axis = 1)

这不会保留步行者的顺序,所以如果这很重要,代码会略有不同。