はじめに
[ITensor][itensor]はtensorを使って1数値計算を行うためのclassや密度行列くりこみ群法(DMRG)などのalgorithmを実行する函数などを提供するC++ libraryです.
開発者がMac愛好家なのかmacOSでのcompileが恐ろしく簡単だったので紹介したいと思います.
ITensorのinstallから有限系のDMRGを実行するところまで行きたいと思います.
ITensorについてもっと詳しく知りたい方は[公式][itensor]が一番詳しいと思いますのでそちらを御覧ください.
こちらでも簡単に紹介されています.
実行環境
macOS Mojave 10.14.3
ITensorのinstall
まずITensor libraryのcompileを行います.
行うことは
- ITensorのcompileに必要なもののinstall
- ITensorのGitHub repositoryのclone
- ITensor libraryのMakefileの設定 (任意)→make
です.
以下で順に説明していきます.
かなり冗長に書いていると思うのでやかましいと思う方は公式をご覧いただくか, 必要な処理を次の節にまとめたのでそれをささっと実行してください.
ITensorのcompileに必要なもののinstall
- C++ compiler
- Git
- Make
- Xcode (BLAS/LAPACK用)
この中でinstallしていないものがあればinstallを行なってください.
install方法は簡単にですが, こちらにまとめています.
なお, 2019年12月現在のITensorの最新versionは3.1.1です.
ITensor3はC++17対応のC++ compiler (Clang v5~) が必要です.
ITensor3は今年releaseされたばかりなので, bugが怖い方はITensor2をcompileしてください.
ITensor2はC++11対応のC++ compiler (Clang v3~) が必要です.
Intel compilerはC++11の機能が完全には提供されていないため非推奨とされています4.
ITensorのGitHub repositoryのclone
ITensorを置きたいdirectoryで以下を実行してください.
git clone https://github.com/ITensor/ITensor itensor
cd itensor
ITensor2をご所望の方は更に
git checkout v2
を実行してください.
ITensor libraryのMakefileの設定 (任意)→make
ここではCommand Line Tools for Xcodeに含まれているC++ compiler Clang++とXcodeに含まれるBLAS/LAPACK (Accelerate Framework) を用いてcompileすることを想定しています.
options.mk.sample
にITensorをcompileするための設定が書いてありますのでoptions.mk
にcopyします:
cp options.mk.sample options.mk
次にeditorなどでoptions.mk
を編集しますが, option.mk
のdefault設定はGNU C++ compiler (g++) なのですが, Command Line Tools for Xcodeを入れている場合, g++
はclang++
へのaliasになっています. したがって編集しない場合compileにはclang++が使われます.
options.mk
にはIntel MKLなどの他のBLAS/LAPACKを用いるためのoptionも記載されていますので, ご自身の環境に合わせて適宜変更してください.
編集が終わったら
make
を実行してください.
ITensorのinstallまとめ
ITensorのversion毎にITensorをinstallするまでのcommandをまとめました. options.mk
を編集してないのでdefault設定でのcompileになります.
ITensor3
git clone https://github.com/ITensor/ITensor itensor
cd itensor
cp options.mk.sample options.mk
make
ITensor2
git clone https://github.com/ITensor/ITensor itensor
cd itensor
git checkout v2
cp options.mk.sample options.mk
make
DMRGの実行(動作確認)
動作確認としてitensor/sample
にある有限系のDMRG dmrg.cc
を実行します5. makeの設定までしてありますので, sample directoryに移動してmake commandを実行するだけです.
cd sample
make
compileが終わったら実行してみましょう.
./dmrg
以下のような感じの出力が出たらcompileできています.
これであなたもあいてんさー!
Initial energy = -99.00000
Sweeps:
1 Maxm=10, Minm=1, Cutoff=1.0E-10, Niter=2, Noise=1.0E-07
2 Maxm=20, Minm=1, Cutoff=1.0E-10, Niter=2, Noise=1.0E-08
3 Maxm=100, Minm=1, Cutoff=1.0E-10, Niter=2, Noise=0.0E+00
4 Maxm=100, Minm=1, Cutoff=1.0E-10, Niter=2, Noise=0.0E+00
5 Maxm=200, Minm=1, Cutoff=1.0E-10, Niter=2, Noise=0.0E+00
vN Entropy at center bond b=50 = 0.581075353146
Eigs at center bond b=50: 0.7840 0.2045 0.0058 0.0024 0.0020 0.0012
Largest m during sweep 1/5 was 10
Largest truncation error: 4.71751e-05
Energy after sweep 1/5 is -138.241288573618
Sweep 1/5 CPU time = 0.0838s (Wall time = 0.0816s)
vN Entropy at center bond b=50 = 0.812720219293
Eigs at center bond b=50: 0.5910 0.3827 0.0078 0.0061 0.0061 0.0058
Largest m during sweep 2/5 was 20
Largest truncation error: 3.83855e-06
Energy after sweep 2/5 is -138.899105014327
Sweep 2/5 CPU time = 0.296s (Wall time = 0.276s)
vN Entropy at center bond b=50 = 0.850686099160
Eigs at center bond b=50: 0.5090 0.4612 0.0075 0.0073 0.0071 0.0071
Largest m during sweep 3/5 was 81
Largest truncation error: 9.98892e-11
Energy after sweep 3/5 is -138.938252544024
Sweep 3/5 CPU time = 1.898s (Wall time = 1.590s)
vN Entropy at center bond b=50 = 0.854386693666
Eigs at center bond b=50: 0.4919 0.4777 0.0075 0.0074 0.0073 0.0073
Largest m during sweep 4/5 was 97
Largest truncation error: 9.99146e-11
Energy after sweep 4/5 is -138.939940458503
Sweep 4/5 CPU time = 4.324s (Wall time = 3.244s)
vN Entropy at center bond b=50 = 0.855234844932
Eigs at center bond b=50: 0.4864 0.4830 0.0074 0.0074 0.0074 0.0074
Largest m during sweep 5/5 was 102
Largest truncation error: 9.99549e-11
Energy after sweep 5/5 is -138.940079532642
Sweep 5/5 CPU time = 6.199s (Wall time = 4.361s)
Ground State Energy = -138.9400795326
Using overlap = -138.9400795326
おまけ:dmrg.cc
の中身
ちなみにdmrg.cc
中身は以下のようになっています(わざわざここに張る必要もないのですが...). やることは計算したいHamilotonian H
, 初期状態 psi
, 計算条件 sweeps
を用意してdmrg
に渡す(そのあと出力されたpsi
で物理量を計算する)というのが基本的な使い方になります.
(2020/3/10追記: version 2かversion 3かで書き方が微妙に異なるのを失念していましたので両versionのものを張り直しました.)
ITensor3
# include "itensor/all.h"
using namespace itensor;
int
main()
{
int N = 100;
//
// Initialize the site degrees of freedom
// Setting "ConserveQNs=",true makes the indices
// carry Sz quantum numbers and will lead to
// block-sparse MPO and MPS tensors
//
//auto sites = SpinHalf(N); //make a chain of N spin 1/2's
auto sites = SpinOne(N); //make a chain of N spin 1's
//
// Use the AutoMPO feature to create the
// next-neighbor Heisenberg model
//
auto ampo = AutoMPO(sites);
for(auto j : range1(N-1))
{
ampo += 0.5,"S+",j,"S-",j+1;
ampo += 0.5,"S-",j,"S+",j+1;
ampo += "Sz",j,"Sz",j+1;
}
auto H = toMPO(ampo);
// Set the initial wavefunction matrix product state
// to be a Neel state.
//
auto state = InitState(sites);
for(auto i : range1(N))
{
if(i%2 == 1) state.set(i,"Up");
else state.set(i,"Dn");
}
auto psi0 = MPS(state);
//
// inner calculates matrix elements of MPO's with respect to MPS's
// inner(psi,H,psi) = <psi|H|psi>
//
printfln("Initial energy = %.5f", inner(psi0,H,psi0) );
//
// Set the parameters controlling the accuracy of the DMRG
// calculation for each DMRG sweep.
// Here less than 5 cutoff values are provided, for example,
// so all remaining sweeps will use the last one given (= 1E-10).
//
auto sweeps = Sweeps(5);
sweeps.maxdim() = 10,20,100,100,200;
sweeps.cutoff() = 1E-10;
sweeps.niter() = 2;
sweeps.noise() = 1E-7,1E-8,0.0;
println(sweeps);
//
// Begin the DMRG calculation
//
auto [energy,psi] = dmrg(H,psi0,sweeps,"Quiet");
//
// Print the final energy reported by DMRG
//
printfln("\nGround State Energy = %.10f",energy);
printfln("\nUsing inner = %.10f", inner(psi,H,psi) );
return 0;
}
ITensor2
# include "itensor/all.h"
using namespace itensor;
int
main()
{
int N = 100;
//
// Initialize the site degrees of freedom.
//
//auto sites = SpinHalf(N); //make a chain of N spin 1/2's
auto sites = SpinOne(N); //make a chain of N spin 1's
//
// Use the AutoMPO feature to create the
// next-neighbor Heisenberg model
//
auto ampo = AutoMPO(sites);
for(int j = 1; j < N; ++j)
{
ampo += 0.5,"S+",j,"S-",j+1;
ampo += 0.5,"S-",j,"S+",j+1;
ampo += "Sz",j,"Sz",j+1;
}
auto H = MPO(ampo);
// Set the initial wavefunction matrix product state
// to be a Neel state.
//
auto state = InitState(sites);
for(int i = 1; i <= N; ++i)
{
if(i%2 == 1)
state.set(i,"Up");
else
state.set(i,"Dn");
}
auto psi = MPS(state);
//
// overlap calculates matrix elements of MPO's with respect to MPS's
// overlap(psi,H,psi) = <psi|H|psi>
//
printfln("Initial energy = %.5f", overlap(psi,H,psi) );
//
// Set the parameters controlling the accuracy of the DMRG
// calculation for each DMRG sweep.
// Here less than 5 cutoff values are provided, for example,
// so all remaining sweeps will use the last one given (= 1E-10).
//
auto sweeps = Sweeps(5);
sweeps.maxm() = 10,20,100,100,200;
sweeps.cutoff() = 1E-10;
sweeps.niter() = 2;
sweeps.noise() = 1E-7,1E-8,0.0;
println(sweeps);
//
// Begin the DMRG calculation
//
auto energy = dmrg(psi,H,sweeps,"Quiet");
//
// Print the final energy reported by DMRG
//
printfln("\nGround State Energy = %.10f",energy);
printfln("\nUsing overlap = %.10f", overlap(psi,H,psi) );
return 0;
}