コンテンツにスキップ

DMRG-04 Gaps

ギャップの計算

DMRG-02 ですでに述べたように、量子系のエネルギーギャップは熱力学極限における第一励起状態と基底状態のエネルギー差として与えられます:

Δ=E1E0 \Delta = E_1 - E_0

つまり、二つの問題を解決する必要があります。(i)有限システムサイズでの次の量の計算:

Δ(L)=E1(L)E0(L) \Delta(L) = E_1 (L) - E_0 (L)

および(ii)Δ(L)\Delta (L) の熱力学極限 L=L= \infty への外挿です。後者は DMRG に固有のものではありませんが、DMRG が開放境界条件を好むため、より一般的な周期境界条件の場合よりもやや複雑です。

有限系のギャップを得る

当然、第一励起状態とそのエネルギーにアクセスできなければなりません。DMRG には基本的に二つの方法があります。一つは常に機能するが洗練されていない方法で、もう一つはより巧妙だが全ての状況で機能するわけではない方法です。

  1. 素朴な方法は、二つの状態を同時に計算する DMRG 計算を設定することです。しかし、与えられた状態数に対して精度はやや低下します。二つの異なる量子状態の両方を正確に記述する必要があるためです。

  2. より巧妙な方法は、ギャップの計算を二つの基底状態の計算に帰着させます。多くの量子系では、基底状態と第一励起状態は良い量子数が異なるため、それぞれの量子数セクターでの基底状態となります。例えば、スピン-1/2 鎖では、基底状態は全スピン 0 の一重項であり、磁化ゼロのセクターでの基底状態です。第一励起状態は全スピン 1 の三重項、すなわち磁化 0 の一つの励起状態と、磁化 +1 および -1 セクターそれぞれの基底状態から成ります。したがって、磁化セクター +1 の基底状態として計算できます。

スピン-1/2 鎖の計算から始めましょう。

例:量子数なし

パラメータファイルを使う場合

以下の例では、スピン S=1/2 鎖のパラメータファイル spin_one_half_gap に一行追加して、第一励起状態のエネルギーも計算したいことをコードに伝えます。アルゴリズムは、基底状態と第一励起状態の両方を標的にする密度行列を構築します。どちらも Sz=0 の同じ部分空間にあります。第一励起状態は三重項なので、これにより一重項-三重項ギャップが得られます:

LATTICE="open chain lattice"
MODEL="spin"
CONSERVED_QUANTUMNUMBERS="N,Sz"
Sz_total=0
J=1
SWEEPS=4
{L=32, MAXSTATES=100
NUMBER_EIGENVALUES=2}

最後の行だけを追加して、計算する固有状態の数を指定したことに注意してください。両方の状態を標的にすることで、アルゴリズムは両方が正確に表現されることを保証します。しかし、100 状態しか保持しない場合、これは完全には当てはまりません。このパラメータファイルで得られた基底状態エネルギーを、基底状態のみを標的にした以前のシミュレーションと比較してみてください。

この例でのエンタングルメントエントロピーは全く意味がないことに注意することが重要です。アルゴリズムは二つの状態を混合した密度行列を計算しているからです。簡単に言うと、アルゴリズムは Sz=0S_z=0 セクターの基底状態と第一励起状態の両方を標的にし、純粋な量子エンタングルメントではなく古典的な混合の不確定性が生じます。エンタングルメントエントロピーを適切に計算するには、一重項セクターと三重項セクターを独立に対角化して、この混合を避ける必要があります。

Python を使う場合

スクリプト spin_one_half_gap.pyDMRG-03 チュートリアルのスピン-1/2 スクリプトと同じシミュレーションを実行しますが、要求する NUMBER_EIGENVALUES を 2 に変更し、これらの固有状態のすべてのデータを読み込みます:

import pyalps
import numpy as np
import matplotlib.pyplot as plt
import pyalps.plot

parms = [ { 
        'LATTICE'                   : "open chain lattice", 
        'MODEL'                     : "spin",
        'CONSERVED_QUANTUMNUMBERS'  : 'N,Sz',
        'Sz_total'                  : 0,
        'J'                         : 1,
        'SWEEPS'                    : 4,
        'L'                         : 32,
        'MAXSTATES'                 : 100,
        'NUMBER_EIGENVALUES'        : 2
       } ]

input_file = pyalps.writeInputFiles('parm_spin_one_half_gap',parms)
res = pyalps.runApplication('dmrg',input_file,writexml=True)

data = pyalps.loadEigenstateMeasurements(pyalps.getResultFiles(prefix='parm_spin_one_half_gap'))

すべての測定値を反復処理しながら、エネルギーを抽出します:

energies = np.empty(0)
for s in data[0]:
    if s.props['observable'] == 'Energy':
        energies = s.y
    else:
        print(s.props['observable'], ':', s.y[0])

そしてギャップを計算します:

energies.sort()
print('Energies:', end=' ')
for e in energies:
    print(e, end=' ')
print('\nGap:', abs(energies[1]-energies[0]))

例:量子数を使う場合

量子数の保存を利用して一重項-三重項ギャップを計算するには、二つの独立したシミュレーションを実行する必要があります。一つは Sz=0、もう一つは Sz=1 で実行します。二つのエネルギーの差がギャップになります。

パラメータファイルを使う場合

これは spin_one_half パラメータファイルの Sz_total の値を変更するだけで済みます:

LATTICE="open chain lattice"
MODEL="spin"
CONSERVED_QUANTUMNUMBERS="N,Sz"
Sz_total=1
SWEEPS=4
J=1
{L=32, MAXSTATES=40}

このファイルはここからダウンロードできます:spin_one_half_triplet

Python を使う場合

スクリプト spin_one_half_triplet.py は二つの Python パラメータ辞書で定義された両 Sz セクターのシミュレーションを実行します:

import pyalps
import numpy as np
import matplotlib.pyplot as plt
import pyalps.plot

parms = []
for sz in [0,1]:
    parms.append( { 
        'LATTICE'                   : "open chain lattice", 
        'MODEL'                     : "spin",
        'CONSERVED_QUANTUMNUMBERS'  : 'N,Sz',
        'Sz_total'                  : sz,
        'J'                         : 1,
        'SWEEPS'                    : 4,
        'L'                         : 32,
        'MAXSTATES'                 : 40,
        'NUMBER_EIGENVALUES'        : 1
       } )
       
input_file = pyalps.writeInputFiles('parm_spin_one_half_triplet',parms)
res = pyalps.runApplication('dmrg',input_file,writexml=True)

通常の方法で結果を読み込んだ後、両セクターの測定値を出力し、各 Sz 値の基底状態エネルギーを辞書に保存します:

data = pyalps.loadEigenstateMeasurements(pyalps.getResultFiles(prefix='parm_spin_one_half_triplet'))

# print results:
energies = {}
for run in data:
    print('S_z =', run[0].props['Sz_total'])
    for s in run:
        print('\t', s.props['observable'], ':', s.y[0])
        if s.props['observable'] == 'Energy':
            sz = s.props['Sz_total']
            energies[sz] = s.y[0]

そして、Sz=1 と Sz=0 セクターのエネルギー差としてギャップを計算できます:

print('Gap:', energies[1]-energies[0])

ギャップの熱力学極限への外挿

最初の試みとして、D=50,100,150D=50,100,150 を固定し、長さ L=32,64,96,128L=32,64,96,128 のギャップを計算します。固定 DD に対して、ギャップ対 1/L1/L をプロットします。小さい DD では、結果はゼロを通る直線上に乗らず、そこから上に曲がって見えるはずです。この振る舞いは DD が大きくなると改善されます(以下の問題を参照)。

より意味のある第二の試みとして、長さ L=32,64,96,128L=32,64,96,128 を固定し、各固定長でのギャップを DD(または上で説明した切り詰め誤差)について外挿するために D=50,100,150,200D=50,100,150,200 を変化させ、これらの外挿値を使ってギャップ対 1/L1/L をプロットします。

下図は固定 D=100D=100 でのスピン-1/2 一重項-三重項ギャップ対 1/L1/L を示しています:四点は小さいが明らかに非ゼロの切片を通る直線の近くに位置し、以下で述べる苦境をまさに示しています——これらの四つの鎖長だけでは、真にゼロのギャップと非常に小さな有限のギャップを区別することが難しいのです。

ファイル spin_one_half_multiple を修正して、異なるシステムサイズと異なる状態数での Sz=0 と Sz=1 のすべての実行を設定します。五回の掃引を使用し、チュートリアルで概説した手順に従ってギャップの値を外挿します。

スピン-1/2 鎖の場合は少し残念です。コンピュータの限界まで押し進めても言えることは、ギャップは計算の精度の範囲内で非常に小さく、したがってゼロになりそうだということです。しかし、ギャップが例えば e50e^{-50} でないとは誰が断言できるでしょうか?これはもちろん、高度に精確な数値的手法でさえ限界があることを冷静に思い起こさせます。

したがって、より報われる問いに目を向けましょう:スピン-1 反強磁性ハイゼンベルク鎖のギャップはいくらでしょうか?

ここで奇妙なひねりがあります。今は単に説明して実行するだけで、後で説明します:磁化セクター 0 と 1 の基底状態間ではなく、1 と 2 の間のギャップを計算します。必要なら後の参照のために 0 と 1 についても計算してください。しかし以下は 1 と 2 についてのものです。

機械精度内で Δ(L)\Delta (L) が得られているとします。上で議論したような適切な外挿によるか、非常に高精度の計算によるかです。前者を行いたくない場合は、システムサイズ L=8,16,32,48,64,96,128,192,256L=8,16,32,48,64,96,128,192,256 のすべてについて D=300D=300 状態と 5 回の掃引でギャップを計算します。

開放端の影響は 1/L1/L で減少するため、まずギャップ Δ(L)\Delta (L)1/L1/L をプロットするのは理にかなっています。これはすでにスピン-1/2 の場合にもそのようなプロットを作成するために行いました。見えるのは、小さい L では相当直線的で、その後上に曲がり始める曲線です。外挿するために漸近的振る舞い(長い長さの曲がった部分)が何であるかを解析的または近似的に知ることが理想的です。そのためにギャップ Δ(L)\Delta (L)1/L21/L^2 のプロットを作成するのが一般的です。

下図は固定 D=200D=200 でのスピン-1 ギャップ対 1/L21/L^2 を示しています:点は今や良い直線上に乗り、受け入れられているハルデンギャップ Δ/J=0.41052\Delta/J=0.41052DMRG-02 参照)に近い切片に外挿されます——以下で導出する 1/L21/L^2 収束と一致しており、上のスピン-1/2 の場合よりもはるかに行儀の良い外挿です。

この手順は実際に次の議論によって動機付けられています:Haldane による非線形シグマ模型でのスピン-1 鎖の解析から、最低の励起(周期境界条件では運動量 kk でラベルできる)は k=πk=\pi 付近にあり、エネルギーは:

E(k)=E0+Δ2+c2(kπ)2. E(k) = E_0 + \sqrt{\Delta^2 + c^2 (k-\pi)^2}.

開放境界条件では kπ1/Lk-\pi \approx 1/L(箱の中の粒子を考えると)と近似でき、有限系サイズのギャップが得られます:

Δ(L)Δ(1+c22Δ2L2) \Delta(L) \approx \Delta \left( 1 + \frac{c^2}{2\Delta^2 L^2} \right)

これは漸近極限では収束が本質的に 1/L21/L^2 であることを示します。

磁化セクター 0 と 1 の基底状態間のギャップも計算した方は、そこで得られるギャップが本質的にゼロであることを示してください。他の方はこの結果を既知のこととして受け入れてください。実際、スピン-1 鎖が開放境界条件でこの奇妙な振る舞いを示す非常に良い理由を解析的に知ることができます。しかし、それを知らなくても、すぐに問題を発見できます!これは局所オブザーバブルを観察することで行えます。

まとめ

DMRG は臨界スピン-1/2 鎖の(おそらくゼロとなる)ギャップとスピン-1 鎖の有限のハルデンギャップを解消しますが、二つの場合は異なる外挿戦略を必要とします——ギャップなしに近い場合は 1/L1/L、ギャップがある場合は 1/L21/L^2——それぞれ異なる長距離物理を反映しています。DMRG-05 では、スピン-1 ギャップを特定的に磁化セクター 1 と 2 の間から読み取る必要がある理由を説明します。

問題

  • 固定の鎖長で DD を増やすと、ギャップ対 1/L1/L プロットの曲率はなぜまっすぐになるのですか?
  • 固定の長さでギャップを DD(または切り詰め誤差)について外挿した後に 1/L1/L に対してプロットすると:固定 DD での最初の試みと比較してプロットはどのように見えますか?
  • スピン-1 鎖の Δ(L)\Delta(L)1/L1/L 曲線の線形な(小 LL)部分だけを素直に外挿すると、どのようなギャップが得られますか?それは過大評価か過小評価ですか?(これは鎖の相関長が非常に長く、到達可能な長さスケールで漸近的な振る舞いを見るのが難しい状況に関連します。)
  • 持っている最も長い鎖からギャップを読み取ると、それは過大評価か過小評価ですか?
  • Δ(L)\Delta(L)1/L1/L の代わりに 1/L21/L^2 に対してプロットすると:長い長さに対して曲線はどのように見えますか?どのようなギャップが外挿されますか?
  • 外挿されたギャップは DMRG-02 の受け入れられている値 Δ/J=0.41052\Delta/J=0.41052 にどれくらい近いですか?
  • 磁化セクター 0 と 1 の間のギャップは本質的にゼロですが、セクター 1 と 2 の間のギャップは有限です。なぜ有限のギャップが物理的に正しくゼロのギャップが誤りなのですか——これは物理的な宝くじですか?