【发布时间】:2020-05-25 05:22:15
【问题描述】:
假设我有一个格子
a = np.array([[1, 1, 1, 1],
[2, 2, 2, 2],
[3, 3, 3, 3],
[4, 4, 4, 4]])
我想创建一个函数func(lattice, start, end),它接受 3 个输入,其中 start 和 end 是函数将对元素求和的行的索引。例如,对于func(a,1,3),它将汇总这些行的所有元素,例如func(a,1,3) = 2+2+2+2+3+3+3+3+4+4+4+4 = 36。
现在我知道这可以通过切片和np.sum() 轻松完成。但至关重要的是,我想要func 做的是也有能力环绕。即func(a,2,4) 应该返回3+3+3+3+4+4+4+4+1+1+1+1。
更多的例子是
func(a,3,4) = 4+4+4+4+1+1+1+1
func(a,3,5) = 4+4+4+4+1+1+1+1+2+2+2+2
func(a,0,1) = 1+1+1+1+2+2+2+2
在我的情况下,我永远不会达到它会再次总结整个事情的地步,即
func(a,3,6) = sum of all elements
更新: 对于我的算法
for i in range(MC_STEPS_NODE):
sweep(lattice, prob, start_index_master, end_index_master,
rows_for_master)
# calculate the energy
Ene = subhamiltonian(lattice, start_index_master, end_index_master)
# calculate the magnetisation
Mag = mag(lattice, start_index_master, end_index_master)
E1 += Ene
M1 += Mag
E2 += Ene*Ene
M2 += Mag*Mag
if i % sites_for_master == 0:
comm.Send([lattice[start_index_master:start_index_master+1], L, MPI.INT],
dest=(rank-1)%size, tag=4)
comm.Recv([lattice[end_index_master:end_index_master+1], L, MPI.INT],
source = (rank+1)%size, tag=4)
start_index_master = (start_index_master + 1)
end_index_master = (end_index_master + 1)
if start_index_master > 100:
start_index_master = start_index_master % L
if end_index_master > 100:
end_index_master = end_index_master % L
我想要的函数是 mag() 函数,它计算子晶格的磁化强度,它只是其所有元素的总和。想象一个LxL 晶格分裂成两个子晶格,一个属于master,另一个属于worker。每个sweep 扫过lattice 的相应子晶格,start_index_master 和end_index_master 确定子晶格的开始行和结束行。对于每个i%sites_for_master = 0,索引通过添加1 向下移动,最终以100 为模,以防止mpi4py 中的内存溢出。所以你可以想象如果子晶格在主晶格的中心,那么start_index_master < end_index_master。最终,子晶格将继续向下移动到start_index_master < end_index_masterend_index_master > L,因此在这种情况下,如果start_index_master = 10 为晶格L=10,则子晶格的最底行是第一行([0])主格子的。
能量函数:
def subhamiltonian(lattice: np.ndarray, col_len_start: int,
col_len_end: int) -> float:
energy = 0
for i in range(col_len_start, col_len_end+1):
for j in range(len(lattice)):
spin = lattice[i%L, j]
nb_sum = lattice[(i%L+1) % L, j] + lattice[i%L, (j+1) % L] + \
lattice[(i%L-1) % L, j] + lattice[i%L, (j-1) % L]
energy += -nb_sum*spin
return energy/4.
这是我计算子晶格能量的函数。
【问题讨论】:
-
效率不高,但您可以在进行切片和求和之前
a.vstack(a)。如果它可以环绕多次,您可以vstack多次。 -
不幸的是,我可能会调用这个函数超过 10^6 次,所以我担心
np.vstack()并不理想 -
不幸的是,我可能会调用这个函数超过 10^6 次 为什么?
-
您需要它只环绕一次还是任意次数?就像第二个值永远不会超过数组长度的两倍?
-
Like @Boris 如果是任意次数,那么使用 recursive 函数会很有帮助。
标签: python numpy slice numpy-slicing