Difference between revisions of "Tutorials:MonteCarloHOWTO/ja"

From ALPS
Jump to: navigation, search
 
Line 3: Line 3:
 
==  概要  ==
 
==  概要  ==
  
ALPSアプリケーションでは、すでにいくつかのモンテカルロ(MC)プログラムが入手可能です。ALPSの主な目的は、開発者が自身のMCプログラムを簡単に、短時間で開発可能なように手助けをすることです。ALPSアプリケーションには、すべてのMCアルゴリズムで実行されるいくつかの普遍的な機能があります。もう再開発の必要はありません。この章では、ALPSライブラリが提案するシンプルなフレームワークを説明し、古典モンテカルロ、量子モンテカルロ法についていくつかの例で演習をおこないます。
+
ALPSアプリケーションでは、すでにいくつかのモンテカルロ(MC)プログラムが入手可能ですが、ALPSの主な目的は、開発者が自身のMCプログラムを簡単に、短時間で開発可能なように手助けをすることです。ALPSアプリケーションには、すべてのMCアルゴリズムで実行されるいくつかの普遍的な機能があり、もう再開発の必要はありません。この章では、ALPSライブラリが提案するシンプルなフレームワークを説明し、古典モンテカルロ、量子モンテカルロ法についていくつかの例で演習をおこないます。
  
 
ALPSソースのexample/schedulerディレクトリにイジングモデルのサンプルがあります。このサンプル計算例を用いて、以下で解説します。
 
ALPSソースのexample/schedulerディレクトリにイジングモデルのサンプルがあります。このサンプル計算例を用いて、以下で解説します。
Line 22: Line 22:
 
* エラーバーと自己相関時間の自動計算
 
* エラーバーと自己相関時間の自動計算
 
* 自動並列化
 
* 自動並列化
* 抽出ツールを使用した計算結果の自動出力(XML形式)
+
* XML形式による計算結果の自動出力とこれらを扱うコマンドラインツール
* 符号の自動制御(量子モンテカルロシミュレーションの符号問題)
+
* 負符号に関するリウェイティング(量子モンテカルロシミュレーションの負符号問題)
* 簡単なチェックポイント、再計算機能
+
* 簡単なチェックポイント作成と、そこからのリスタート機能
 
* 入力パラメータの容易な制御
 
* 入力パラメータの容易な制御
* 新しい測定を容易に追加
+
* 測定の追加が容易
 
* 乱数の容易な取扱い
 
* 乱数の容易な取扱い
 
* 格子の容易な取扱い
 
* 格子の容易な取扱い
Line 38: Line 38:
 
'''このチュートリアルは未完成です。コメント、ご提案があれば"comp-phys-alps-users@lists.comp-phys.org"までお願いします。'''
 
'''このチュートリアルは未完成です。コメント、ご提案があれば"comp-phys-alps-users@lists.comp-phys.org"までお願いします。'''
  
まず最初に、ALPSライブラリを使用するためにC++言語をプログラム言語としてください。今から、新しいMCアプリケーションの開発をおこない、シングルモンテカルロステップで使用される内部データ構造やアルゴリズムは分かっているものと仮定します。
+
まず最初に、ALPSライブラリを使用するためにC++言語を使ってください。また、新しいMCアプリケーションの開発をおこなうが、使うべき内部データ構造やアルゴリズムは分かっているものと仮定します。
  
ALPSライブラリを使うために、新しいC++クラスが必要です。このクラスは内部ALPSクラスとは分離されています。このクラスをMyMonteCarloと呼び、MyMonteCarlo.hppヘッダーファイルを生成してください。
+
ALPSライブラリを使うために、ALPSで定義されたクラスから継承した、自分のMC 用のクラスを定義します。今回はこのクラスをMyMonteCarloと呼び、MyMonteCarlo.hppヘッダーファイルに定義します。
  
 
   #ifndef MYMC_HPP
 
   #ifndef MYMC_HPP
Line 65: Line 65:
 
   #endif
 
   #endif
  
各ラインが何を意味するか説明していきます。
+
各行が何を意味するか説明していきます。
  
 
* 最初に、ALPSのヘッダーファイルをインクルードする必要があります。(他のALPS関数を利用する場合は、さらに追加する必要あり)
 
* 最初に、ALPSのヘッダーファイルをインクルードする必要があります。(他のALPS関数を利用する場合は、さらに追加する必要あり)
* ALPSクラスから派生させることによってMyMonteCarloクラスを定義します。上記のヘッダーファイルは、最も簡単なクラスであるMCRun ALPSクラスを使用することを意味しています。もしALPSの格子機能を使用したい場合は、次のように置き換えてください。
+
* ALPSで定義されているクラスから派生させることによってMyMonteCarloクラスを定義します。上記のヘッダーファイルでは、最も簡単なクラスである<tt>alps::csheduler::MCRun</tt>クラスを使用することを意味しています。もしALPSの格子機能を使用したい場合は、次のように置き換えてください。
  
 
   class MyMonteCarlo : public alps::scheduler::LatticeMCRun<>{
 
   class MyMonteCarlo : public alps::scheduler::LatticeMCRun<>{
Line 76: Line 76:
 
   #include <alps/lattice.h>
 
   #include <alps/lattice.h>
  
もし、さらにモデルライブラリ(格子量子モデル)を使用する場合は、次の用に置き換えてください。
+
もし、さらにモデルライブラリ(格子量子モデル)を使用する場合は、次の様に置き換えてください。
  
 
   class MyMonteCarlo : public alps::scheduler::LatticeModelMCRun<>{
 
   class MyMonteCarlo : public alps::scheduler::LatticeModelMCRun<>{
  
* publicにある、MyMonteCarlo(const alps::ProcessList&,const alps::Parameters&,int)はコンストラクターです。そして、すべてのパラメータの初期化が必要でしょう。
+
* publicにある、<tt>MyMonteCarlo(const alps::ProcessList&,const alps::Parameters&,int)</tt>はコンストラクタです。そして、すべてのパラメータの初期化が必要でしょう。
* print_copyright(std::ostream&)は、各シミュレーションの最初の部分をアウトプットするかどうか設定する関数です。
+
* <tt>print_copyright(std::ostream&)</tt>は、各シミュレーションの最初に、任意の情報を表示する関数です。
* save,loadは、各チェックポイントの後で再スタートするために、何がディスク上にsave(load)する必要があるか決定する関数です。
+
* <tt>save</tt>,<tt>load</tt>は、各チェックポイントの後で再スタートするために、何がディスク上にsave(load)する必要があるか決定する関数です。
* dostep関数はMC関数のメインです。あらゆるMDステップで実行されます。
+
* <tt>dostep</tt>関数はMCの中心となる関数です。毎回のMCステップごとに実行されます。
* is_thermalizedは熱化のパートのシミュレーションがいつ終わったかALPSライブラリに教える関数です。
+
* <tt>is_thermalized</tt>は熱平衡化が終わっているかどうかをALPSライブラリに伝える関数です。
* work_doneは、シミュレーションの何パーセントが実行済みかALPSライブラリに教える関数です。 
+
* <tt>work_done</tt>は、シミュレーションの何パーセントが実行済みかALPSライブラリに伝える関数です。 
  
最後に、これらの関数とプログラムを正しく結びつけるプログラム、MyMonteCarlo.cppを準備します。
+
最後に、これらの関数を正しく呼びだすプログラムを、MyMonteCarlo.cppとして書きます。
  
===  The copyright function  ===-->
+
==  ALPS MCプログラムの作成 ==
==  ALPS MCプログラムのビルド ==
+
===  <tt>copyright</tt>関数 ===
===  copyright関数 ===
 
  
まず、MyMonteCarlo.cppの中で最も簡単なprint_copyright()関数から始めます。
+
まず、MyMonteCarlo.cppの中で最も簡単な<tt>print_copyright()</tt>関数から始めます。
  
 
   #include "MyMonteCarlo.hpp";
 
   #include "MyMonteCarlo.hpp";
Line 107: Line 106:
 
===  モンテカルロステップの制御  ===
 
===  モンテカルロステップの制御  ===
  
次に、MCステップについて説明します。典型的な例は次の通りです。まず、熱化のためステップ数を決め、続いて、測定領域のステップ数を決めます。普通、各計測の間にモンテカルロステップを実行します。よって、内部データ構造で、次の変数(in MyMonteCarlo.hpp)を設定することで実行可能です。
+
次に、MCステップについて説明します。典型的な例は次の通りです。まず、平衡化のためにある一定のステップ数だけ更新し、続いて、あらかじめ決めておいた回数だけ更新しながら物理量を測定します。普通、各測定の間に何回かのモンテカルロステップを実行します。これは、内部データ構造で、次の変数(in MyMonteCarlo.hpp)を設定することで実現できます。
  
 
   private :
 
   private :
Line 121: Line 120:
 
   };
 
   };
  
Nb_Thermalisation_Stepsは熱化ステップ数、Nb_Stepsは熱化後のMCステップ数です。Each_Measuremenは各測定のステップ数をあらわします。これらの3つの数字はコンストラクタで初期化されます。Steps_Done_TotalはMCが終わったステップの番号を保存します。最後に、Measurements_Done willは各測定の計算し終わった途中のステップ数を保存します。The do_update()とdo_measurements()関数はそれぞれ各一回のMCステップで実行されます。
+
<tt>Nb_Thermalisation_Steps</tt>は平衡化ステップ数、<tt>Nb_Steps</tt>は平衡化後のMCステップ数です。<tt>Each_Measuremen</tt>は各測定のステップ数をあらわします。これらの3つの数字はコンストラクタで初期化します。<tt>Steps_Done_Total</tt>は、今までに平衡化も含めて何回更新したのかを保存します。最後に、<tt>Measurements_Done</tt>は前回の測定から何回更新したのかを保存します。<tt>do_update()</tt>と<tt>do_measurements()</tt>関数はそれぞれ毎回のMC更新時および測定時に実行されます。
  
これらすべての定義はMyMonteCarlo.cppでクラスメンバー関数のシンプルな定義となります。
 
  
 
   bool MyMonteCarlo::is_thermalized() const
 
   bool MyMonteCarlo::is_thermalized() const
 
     {  return (Steps_Done_Total >= Nb_Thermalisation_Steps); }
 
     {  return (Steps_Done_Total >= Nb_Thermalisation_Steps); }
  
この間数は、現在のMCステップ数が熱化ステップのトータル番号より大きいとき、1を返し、それ以外は0を返します。
+
この関数は、現在のMCステップ数が平衡化ステップ数より大きいとき、<tt>true</tt>を返し、それ以外は<tt>false</tt>を返します。
  
 
   double MyMonteCarlo::work_done() const
 
   double MyMonteCarlo::work_done() const
 
   { return (is_thermalized() ? (Steps_Done_Total-Nb_Thermalisation_Steps)/double(Nb_Steps) :0.); }
 
   { return (is_thermalized() ? (Steps_Done_Total-Nb_Thermalisation_Steps)/double(Nb_Steps) :0.); }
  
シミュレーションが熱化しなければ0を返し、測定ステップがどれくらい実行されているかパーセンテージを与えます。最後に、dostep()関数は次のようになります。
+
シミュレーションが平衡化していなければ0を返し、そうでなければ測定ステップのうちどれだけが実行されたかを返します。最後に、<tt>dostep()</tt>関数は次のようになります。
  
 
   void MyMonteCarlo::dostep()
 
   void MyMonteCarlo::dostep()
Line 146: Line 144:
 
   }
 
   }
  
いくつかのポイントで、do_update()によっておこなわれる、MCステップ中に何をおこなうのか?ちゃんと調べなければいけません。計測は例にあるdo_measurements()関数を参照してください。
+
もちろん、あなたのMC計算の、1回のMCステップの間に行われることは、あなた自身で定義しなければなりません。それを<tt>do_update()</tt> 関数の中に実装してください。
 +
測定は、後述する<tt>do_measurement()</tt>関数の中でまとめて行います。
  
 
===  セーブ、ロード関数  ===
 
===  セーブ、ロード関数  ===
  
ALPSには計算中の内部データをディスクにチェックポイントを生成する機能があります。チェックポイントほ利用して計算を再スタートするために、整数データと倍精度の配列が必要になります。
+
ALPSには計算中の内部データをディスクにチェックポイントとして生成する機能があります。今回は、チェックポイントを利用して計算を再スタートするために、整数変数と倍精度浮動小数点数の配列が必要になると仮定します。
  
 
   private :
 
   private :
Line 160: Line 159:
 
   };
 
   };
  
設定は簡単です。
+
<tt>save</tt>関数は簡単にかけて、
  
 
   void MyMonteCarlo::save(alps::ODump& dump) const
 
   void MyMonteCarlo::save(alps::ODump& dump) const
 
     { dump <<  Number_of_Spins << MyOwnVariable << SpinArray;}
 
     { dump <<  Number_of_Spins << MyOwnVariable << SpinArray;}
  
load関数は簡単に推測できます。
+
<tt>load</tt>関数も対となる<tt>save</tt>から簡単に実装できます。
  
   void MyMonteCarlo::load(alps::IDump& dump) const
+
   void MyMonteCarlo::load(alps::IDump& dump)
 
     { dump >>  Number_of_Spins >> MyOwnVariable >> SpinArray;}
 
     { dump >>  Number_of_Spins >> MyOwnVariable >> SpinArray;}
  
ここで、ダンプの方法を説明します。一般的な型(int,double,boolなど)や一般的なコンテナ(vectorやset)が対応可能です。
+
ここで、ダンプの方法を説明します。一般的な型(<tt>int</tt>,<tt>double</tt>,<tt>bool</tt>など)や一般的なコンテナ(<tt>vector</tt>や<tt>set</tt>)が対応可能です。
  
次のような内部構造を持っているとすると、
+
次のような構造体を定義したとします。
  
 
   struct Vertex
 
   struct Vertex
Line 179: Line 178:
 
     int SomeOtherVariable; }
 
     int SomeOtherVariable; }
  
モンテカルロクラスでインスタンス化し保存したいと考えると、
+
この構造体のインスタンスを、自分のモンテカルロクラスの使って保存したいと考えると、
  
 
   private :
 
   private :
Line 187: Line 186:
 
     };
 
     };
  
構造の中で、何を保存、ロードするのかをALPSに指示しなくてはいけません。
+
構造体の中で、何を保存、読み出しするのかをALPSに指示しなくてはいけません。
  
 
   alps::ODump& operator<<(alps::ODump& dump, const Vertex& v)
 
   alps::ODump& operator<<(alps::ODump& dump, const Vertex& v)
Line 195: Line 194:
 
   { return dump >> v.vertex_type >> v.coordinates;}
 
   { return dump >> v.vertex_type >> v.coordinates;}
  
そして、ALPSのsave,load関数のMyVertexを追加することが容易にできます。
+
こうすることで、ALPSのsave,load関数に<tt>Vertex</tt>型の変数<tt>MyVertex</tt>を追加することが容易にできます。
  
 
   void MyMonteCarlo::save(alps::ODump& dump) const
 
   void MyMonteCarlo::save(alps::ODump& dump) const
Line 208: Line 207:
 
===  do_measurements()関数 ===
 
===  do_measurements()関数 ===
  
物理量の計測の実行方法です。次の例を参照してください。
+
この関数では、物理量を測定し、ALPSに引渡します。
  
 
   void MyMonteCarlo::do_measurements()
 
   void MyMonteCarlo::do_measurements()
Line 220: Line 219:
 
     }
 
     }
  
わかりますか?驚くかもしれませんが、ALPSは "Energy"や"Spin Correlations"をどうやって知るのか?また、スカラー値(エネルギーなど)とベクター値(相関)をどうやって区別するのか?この2つの疑問は、クラスのコンストラクタで以下の用に対処されます。
+
わかりますか?驚いたかもしれませんね。ALPSは "Energy"や"Spin Correlations"をどうやって知るのか?また、スカラー値(エネルギーなど)とベクター値(相関関数など)をどうやって区別するのか?この2つの疑問は、クラスのコンストラクタで以下の用に対処されます。
  
他では、なぜベクター計測値にstd::vectorではなく、std::vectorを使用しているのか?これはALPS内部の問題に起因しています。ALPSは各測定値で常に同じサイズである必要があるからです。
+
他では、なぜベクター計測値にstd::vectorではなく、std::valarrayを使用しているのか?これはALPS内部の問題に起因しています。ALPSは各測定値が常に同じサイズであることを要請します。

Latest revision as of 11:21, 23 August 2012

概要

ALPSアプリケーションでは、すでにいくつかのモンテカルロ(MC)プログラムが入手可能ですが、ALPSの主な目的は、開発者が自身のMCプログラムを簡単に、短時間で開発可能なように手助けをすることです。ALPSアプリケーションには、すべてのMCアルゴリズムで実行されるいくつかの普遍的な機能があり、もう再開発の必要はありません。この章では、ALPSライブラリが提案するシンプルなフレームワークを説明し、古典モンテカルロ、量子モンテカルロ法についていくつかの例で演習をおこないます。

ALPSソースのexample/schedulerディレクトリにイジングモデルのサンプルがあります。このサンプル計算例を用いて、以下で解説します。

 ALPSライブラリを使用する利点 

  •  エラーバーと自己相関時間の自動計算
  •  自動並列化
  •  XML形式による計算結果の自動出力とこれらを扱うコマンドラインツール
  •  負符号に関するリウェイティング(量子モンテカルロシミュレーションの負符号問題)
  •  簡単なチェックポイント作成と、そこからのリスタート機能
  •  入力パラメータの容易な制御
  •  測定の追加が容易
  •  乱数の容易な取扱い
  •  格子の容易な取扱い
  •  量子ハミルトニアンの容易な取扱い(量子モンテカルロ計算)
  • ...

わずかなプログラミング/移植によって、これらの利点が得られます。

ALPS MCプログラム使用の第一歩

このチュートリアルは未完成です。コメント、ご提案があれば"comp-phys-alps-users@lists.comp-phys.org"までお願いします。

まず最初に、ALPSライブラリを使用するためにC++言語を使ってください。また、新しいMCアプリケーションの開発をおこなうが、使うべき内部データ構造やアルゴリズムは分かっているものと仮定します。

ALPSライブラリを使うために、ALPSで定義されたクラスから継承した、自分のMC 用のクラスを定義します。今回はこのクラスをMyMonteCarloと呼び、MyMonteCarlo.hppヘッダーファイルに定義します。

 #ifndef MYMC_HPP
 #define MYMC_HPP
 #include <alps/scheduler.h>
 #include <alps/alea.h>
 #include <alps/scheduler/montecarlo.h>
 #include <alps/osiris.h>
 #include <alps/osiris/dump.h>
 #include <alps/expression.h>
 using namespace std;
 class MyMonteCarlo : public alps::scheduler::MCRun{
 public :
   MyMonteCarlo(const alps::ProcessList &,const alps::Parameters &,int);
   static void print_copyright(std::ostream &);
   void save(alps::ODump &) const;
   void load(alps::IDump &);
   void dostep();
   bool is_thermalized() const;
   double work_done() const;
 private :
 // your own internal data here ...
 };
 #endif

各行が何を意味するか説明していきます。

  •  最初に、ALPSのヘッダーファイルをインクルードする必要があります。(他のALPS関数を利用する場合は、さらに追加する必要あり)
  •  ALPSで定義されているクラスから派生させることによってMyMonteCarloクラスを定義します。上記のヘッダーファイルでは、最も簡単なクラスであるalps::csheduler::MCRunクラスを使用することを意味しています。もしALPSの格子機能を使用したい場合は、次のように置き換えてください。
 class MyMonteCarlo : public alps::scheduler::LatticeMCRun<>{

ヘッダーの追加もおこなってください。

 #include <alps/lattice.h>

もし、さらにモデルライブラリ(格子量子モデル)を使用する場合は、次の様に置き換えてください。

 class MyMonteCarlo : public alps::scheduler::LatticeModelMCRun<>{
  •  publicにある、MyMonteCarlo(const alps::ProcessList&,const alps::Parameters&,int)はコンストラクタです。そして、すべてのパラメータの初期化が必要でしょう。
  •  print_copyright(std::ostream&)は、各シミュレーションの最初に、任意の情報を表示する関数です。
  •  save,loadは、各チェックポイントの後で再スタートするために、何がディスク上にsave(load)する必要があるか決定する関数です。
  •  dostep関数はMCの中心となる関数です。毎回のMCステップごとに実行されます。
  •  is_thermalizedは熱平衡化が終わっているかどうかをALPSライブラリに伝える関数です。
  •  work_doneは、シミュレーションの何パーセントが実行済みかALPSライブラリに伝える関数です。 

最後に、これらの関数を正しく呼びだすプログラムを、MyMonteCarlo.cppとして書きます。

ALPS MCプログラムの作成

copyright関数

まず、MyMonteCarlo.cppの中で最も簡単なprint_copyright()関数から始めます。

 #include "MyMonteCarlo.hpp";
 /************************************ ALPS functions **********************************************/
 // Copyright statement
 void MyMonteCarlo::print_copyright(std::ostream & out)
 {
   out << "My own ALPS Monte Carlo program v. 0.1\n"
       << "  copyright (c) 2006 by Myself,\n"
       << "  available from the author on request\n\n";
 }

モンテカルロステップの制御

次に、MCステップについて説明します。典型的な例は次の通りです。まず、平衡化のためにある一定のステップ数だけ更新し、続いて、あらかじめ決めておいた回数だけ更新しながら物理量を測定します。普通、各測定の間に何回かのモンテカルロステップを実行します。これは、内部データ構造で、次の変数(in MyMonteCarlo.hpp)を設定することで実現できます。

 private :
  // your own internal data here ...
  int Nb_Steps; 
  int Nb_Thermalisation_Steps; 
  int Each_Measurement;
  int Steps_Done_Total; 
  int Measurements_Done;
  void do_update();
  void do_measurements();
  // the rest of your own internal data here ...
 };

Nb_Thermalisation_Stepsは平衡化ステップ数、Nb_Stepsは平衡化後のMCステップ数です。Each_Measuremenは各測定のステップ数をあらわします。これらの3つの数字はコンストラクタで初期化します。Steps_Done_Totalは、今までに平衡化も含めて何回更新したのかを保存します。最後に、Measurements_Doneは前回の測定から何回更新したのかを保存します。do_update()do_measurements()関数はそれぞれ毎回のMC更新時および測定時に実行されます。


 bool MyMonteCarlo::is_thermalized() const
   {  return (Steps_Done_Total >= Nb_Thermalisation_Steps); }

この関数は、現在のMCステップ数が平衡化ステップ数より大きいとき、trueを返し、それ以外はfalseを返します。

 double MyMonteCarlo::work_done() const
 { return (is_thermalized() ? (Steps_Done_Total-Nb_Thermalisation_Steps)/double(Nb_Steps) :0.); }

シミュレーションが平衡化していなければ0を返し、そうでなければ測定ステップのうちどれだけが実行されたかを返します。最後に、dostep()関数は次のようになります。

 void MyMonteCarlo::dostep()
 { do_update(); // you'll have to define what this function does later
   ++Steps_Done_Total; // increment the number of steps done
   if (is_thermalized()) // do measurements only if simulation thermalized
     { if (++Measurements_Done==Each_Measurement) // do a measurement every Each_Measurement
       { Measurements_Done=0;
       do_measurements(); // you'll have to define what this function does later
       }
    }
 }

もちろん、あなたのMC計算の、1回のMCステップの間に行われることは、あなた自身で定義しなければなりません。それをdo_update() 関数の中に実装してください。 測定は、後述するdo_measurement()関数の中でまとめて行います。

セーブ、ロード関数

ALPSには計算中の内部データをディスクにチェックポイントとして生成する機能があります。今回は、チェックポイントを利用して計算を再スタートするために、整数変数と倍精度浮動小数点数の配列が必要になると仮定します。

 private :
  // the rest of your own internal data here ...
  int Number_of_Spins; 
  int MyOwnVariable;
  std::vector<double> SpinArray;
  ...
 };

save関数は簡単にかけて、

 void MyMonteCarlo::save(alps::ODump& dump) const
   { dump <<  Number_of_Spins << MyOwnVariable << SpinArray;}

load関数も対となるsaveから簡単に実装できます。

 void MyMonteCarlo::load(alps::IDump& dump)
   { dump >>  Number_of_Spins >> MyOwnVariable >> SpinArray;}

ここで、ダンプの方法を説明します。一般的な型(int,double,boolなど)や一般的なコンテナ(vectorset)が対応可能です。

次のような構造体を定義したとします。

 struct Vertex
   { int vertex_type;
    std::vector<double> coordinates;
    int SomeOtherVariable; }

この構造体のインスタンスを、自分のモンテカルロクラスの使って保存したいと考えると、

 private :
    // the rest of your own internal data here ...
    Vertex MyVertex; 
    ...
   };

構造体の中で、何を保存、読み出しするのかをALPSに指示しなくてはいけません。

 alps::ODump& operator<<(alps::ODump& dump, const Vertex& v)
 { return dump << v.vertex_type << v.coordinates; }
 alps::IDump& operator>>(alps::IDump& dump, Vertex& v)
 { return dump >> v.vertex_type >> v.coordinates;}

こうすることで、ALPSのsave,load関数にVertex型の変数MyVertexを追加することが容易にできます。

 void MyMonteCarlo::save(alps::ODump& dump) const
   { dump <<  Number_of_Spins << MyOwnVariable << SpinArray << MyVertex;}

もし、上記のようにモンテカルロステップ数を設定したならば、save/load関数は次の用に加えることができます。

 void MyMonteCarlo::save(alps::ODump& dump) const
   { dump <<  Number_of_Spins << MyOwnVariable << SpinArray << MyVertex;
     dump <<  Nb_Steps << Measurements_Done; }

do_measurements()関数

この関数では、物理量を測定し、ALPSに引渡します。

 void MyMonteCarlo::do_measurements()
   { double Energy; std::valarray<double> Correl(L);
     // do the measurements in your code (update the Energy and Correl variable) ...
     ...
     // give them to ALPS
     measurements["Energy"] << Energy;
     measurements["Spin Correlations"] << Correl;
   }

わかりますか?驚いたかもしれませんね。ALPSは "Energy"や"Spin Correlations"をどうやって知るのか?また、スカラー値(エネルギーなど)とベクター値(相関関数など)をどうやって区別するのか?この2つの疑問は、クラスのコンストラクタで以下の用に対処されます。

他では、なぜベクター計測値にstd::vectorではなく、std::valarrayを使用しているのか?これはALPS内部の問題に起因しています。ALPSは各測定値が常に同じサイズであることを要請します。