3

我有一种非常紧凑的方法来使用 itertools、lambda 函数和大型 NumPy 数组来计算类似 Ising 的模型的分区函数。给定一个由N节点和Q“状态”/节点组成的网络,我有两个数组,h-fields 和J-couplings,大小分别为(N,Q)(N,N,Q,Q)。然而,J 是上三角形。使用这些数组,我一直在Z使用以下方法计算分区函数:

# Set up lambda functions and iteration tuples of the form (A_1, A_2, ..., A_n)
iters = itertools.product(range(Q),repeat=N)
hf = lambda s: h[range(N),s]
jf = lambda s: np.array([J[fi,fj,s[fi],s[fj]] \
                            for fi,fj in itertools.combinations(range(N),2)]).flatten()

# Initialize and populate partition function array
pf = np.zeros(tuple([Q for i in range(N)]))
for it in iters:
    hterms = np.exp(hf(it)).prod()
    jterms = np.exp(-jf(it)).prod()
    pf[it] = jterms * hterms

# Calculates partition function
Z = pf.sum()

这种方法适用于小型NQ比如说(N,Q) = (5,2)。但是,对于较大的系统,由于内存问题(N,Q) = (18,3),此方法甚至无法创建数组,因为它具有非平凡元素。关于如何克服此内存问题或如何更改代码以在子数组上工作的任何想法?pfQ^N

编辑:在定义中犯了一个小错误jf。它已得到纠正。

4

3 回答 3

2

您可以通过将 Z 初始化为 0 并jterms * iterms在每次迭代中递增它来避免大数组。但是,这仍然不会让您摆脱对 Q^N 数字的计算和求和。为此,您可能需要想办法以代数方式简化配分函数。

于 2012-09-11T16:38:32.073 回答
1

不确定您要计算什么,但我使用 ChrisB 建议测试了您的代码,并且 jf 不适用于 Q=3。

于 2012-09-12T10:14:16.180 回答
-1

也许您不应该使用密集的 numpy 数组来编码您的函数?您可以尝试使用稀疏数组或直接使用 Numba 编译的 Python。 这篇博文展示了在简单的 Ising 模型上使用 Numba 并具有良好的性能。

于 2015-05-03T17:05:30.803 回答