itertools、ラムダ関数、および大きな NumPy 配列を使用して、Ising のようなモデルの分割関数を計算するかなりコンパクトな方法がありました。N
ノードとQ
「状態」/ノードで構成されるネットワークが与えられた場合、サイズがそれぞれ と の 2 つの配列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()
この方法は、小さいN
とQ
、たとえばの場合にすばやく機能します(N,Q) = (5,2)
。ただし、大規模なシステムの場合、この方法では重要な要素が含まれるため、メモリの問題により配列を(N,Q) = (18,3)
作成することさえできません。このメモリの問題を克服する方法、またはサブアレイで動作するようにコードを変更する方法についてのアイデアはありますか?pf
Q^N
編集: の定義に小さな誤りがありましたjf
。修正済みです。