エラーの紹介
数値計算ライブラリITensorを使っているときに
このようなエラー文が出て困った経験はないでしょうか?
Warning: Calling `inner(x::MPS, A::MPO, y::MPS)` where the site indices of the `MPS`
│ `x` and the `MPS` resulting from contracting `MPO` `A` with `MPS` `y` don't
│ match is deprecated as of ITensors v0.3 and will result in an error in ITensors
│ v0.4. The most common cause of this is something like the following:
indices ~ dont't match
とあり、インデックスになんらかの不整合があるようです。
以下のコードを実行することでエラーが出てきます。
using ITensors, ITensorMPS
site = siteinds("S=1/2", 10)
psi0 = randomMPS(site)
function Ising_Hamiltonian(N::Int)
os = OpSum()
for j in 1:N-1
os += "Sz", j, "Sz", j+1
end
return os
end
H = MPO(Ising_Hamiltonian(10), site)
#psi0のエネルギー期待値計算
psi1 = H * psi0
E = inner(psi0, psi1)
psi0
の状態におけるエネルギー期待値を計算しようとしています。psi0
にハミルトニアンH
を作用させてpsi1
を得ます。inner
でpsi0
とpsi1
の内積をとることで、期待値$ \langle \psi_0 | H | \psi_0 \rangle $が得られるはずです。
一見して問題はなさそうです。
解説
エラーの原因を一言で表すと、
"インデックスのもつプライムレベルの不一致" です。
まず、MPS
型変数であるpsi0
とpsi1
の1番目のサイトインデックスを確認してみましょう。
println(siteind(psi0,1))
println(siteind(psi1,1))
出力は
(dim=2|id=307|"S=1/2,Site,n=1")
(dim=2|id=307|"S=1/2,Site,n=1")'
となります。psi1
のサイトインデックスにだけ'
が付いていることが分かります。
この'
の個数はインデックスのプライムレベルと呼ばれます。
ITensor内部では、プライムレベルの異なるインデックスは別物と見なされます。そのため縮約が取れなくなり、inner
がうまく働いていません。これがエラー文の意味するところです。
考察
"プライムレベルはどこで変わってしまったのか?"
その原因を探るために、MPO
型変数であるH
の1番目のインデックスを表示してみましょう。
println(inds(H[1]))
出力は
((dim=3|id=394|"Link,l=1"), (dim=2|id=31|"S=1/2,Site,n=1")', (dim=2|id=31|"S=1/2,Site,n=1"))
となります。リンクインデックス(dim=3|id=394|"Link,l=1")
を除けば、2つのサイトインデックス(dim=2|id=31|"S=1/2,Site,n=1")', (dim=2|id=31|"S=1/2,Site,n=1")
をもっていることが分かります。
さらにサイトインデックスのうち片方はプライムレベル1です。
実は、MPO
関数でMPO
型変数を生成する際、同サイトを指すインデックスは異なるプライムレベルをもつように生成されます。
psi1 = H * psi0
としたことで、H
とpsi1
の間でプライムレベル0のインデックスが縮約され、psi1
にはプライムレベル1のインデックスのみが残ったという訳でした。
最後に
関数noprime
を使ってプライムレベルを0にすれば、うまく縮約を取ることができます。
psi1 = H * psi0
psi1 = noprime(psi1)
E = inner(psi0, psi1)
こんな感じです。