3

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()

この方法は、小さいNQ、たとえばの場合にすばやく機能します(N,Q) = (5,2)。ただし、大規模なシステムの場合、この方法では重要な要素が含まれるため、メモリの問題により配列を(N,Q) = (18,3)作成することさえできません。このメモリの問題を克服する方法、またはサブアレイで動作するようにコードを変更する方法についてのアイデアはありますか?pfQ^N

編集: の定義に小さな誤りがありましたjf。修正済みです。

4

3 に答える 3

2

jterms * itermsZ を 0 に初期化し、反復ごとにインクリメントするだけで、大きな配列を回避できます。ただし、これでも 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 に答える