Difference between revisions of "Tutorials:MonteCarloHOWTO/ja"

From ALPS
Jump to: navigation, search
(Created page with "{{Languages|Tutorials:MonteCarloHOWTO}} == 概要 == <!--While several Monte Carlo (MC) programs are already available in the ALPS applications, the main purpose of ALPS is t…")
 
 
(One intermediate revision by one other user not shown)
Line 3: Line 3:
 
==  概要  ==
 
==  概要  ==
  
<!--While several Monte Carlo (MC) programs are already available in the ALPS applications, the main purpose of ALPS is to help developers to program their own MC program in the easiest and quickest possible way. There are several common tasks performed by all MC algorithms which do not need to be re-programmed each time. The goal of this article is to convince that the ALPS libraries propose a simple framework to do so, and to demonstrate with examples how to use them. This includes both classical Monte Carlo as well as Quantum Monte Carlo algorithms.-->
+
ALPSアプリケーションでは、すでにいくつかのモンテカルロ(MC)プログラムが入手可能ですが、ALPSの主な目的は、開発者が自身のMCプログラムを簡単に、短時間で開発可能なように手助けをすることです。ALPSアプリケーションには、すべてのMCアルゴリズムで実行されるいくつかの普遍的な機能があり、もう再開発の必要はありません。この章では、ALPSライブラリが提案するシンプルなフレームワークを説明し、古典モンテカルロ、量子モンテカルロ法についていくつかの例で演習をおこないます。
 
 
<!--The directory example/scheduler in the ALPS sources contains an example simulation code for the Ising model that can be adapted to your needs. In the following we will discuss these examples.-->
 
ALPSアプリケーションでは、すでにいくつかのモンテカルロ(MC)プログラムが入手可能です。ALPSの主な目的は、開発者が自身のMCプログラムを簡単に、短時間で開発可能なように手助けをすることです。ALPSアプリケーションには、すべてのMCアルゴリズムで実行されるいくつかの普遍的な機能があります。もう再開発の必要はありません。この章では、ALPSライブラリが提案するシンプルなフレームワークを説明し、古典モンテカルロ、量子モンテカルロ法についていくつかの例で演習をおこないます。
 
  
 
ALPSソースのexample/schedulerディレクトリにイジングモデルのサンプルがあります。このサンプル計算例を用いて、以下で解説します。
 
ALPSソースのexample/schedulerディレクトリにイジングモデルのサンプルがあります。このサンプル計算例を用いて、以下で解説します。
  
<!--===  What are the advantages of the ALPS libraries over one's own tools for developing a new MC application ?-->
 
 
=== ALPSライブラリを使用する利点 ===
 
=== ALPSライブラリを使用する利点 ===
  
Line 26: Line 22:
 
* エラーバーと自己相関時間の自動計算
 
* エラーバーと自己相関時間の自動計算
 
* 自動並列化
 
* 自動並列化
* 抽出ツールを使用した計算結果の自動出力(XML形式)
+
* XML形式による計算結果の自動出力とこれらを扱うコマンドラインツール
* 符号の自動制御(量子モンテカルロシミュレーションの符号問題)
+
* 負符号に関するリウェイティング(量子モンテカルロシミュレーションの負符号問題)
* 簡単なチェックポイント、再計算機能
+
* 簡単なチェックポイント作成と、そこからのリスタート機能
 
* 入力パラメータの容易な制御
 
* 入力パラメータの容易な制御
* 新しい測定を容易に追加
+
* 測定の追加が容易
 
* 乱数の容易な取扱い
 
* 乱数の容易な取扱い
 
* 格子の容易な取扱い
 
* 格子の容易な取扱い
Line 36: Line 32:
 
* ...
 
* ...
  
<!--All this comes with only a small amount of programming/modification that we describe now.-->
 
 
わずかなプログラミング/移植によって、これらの利点が得られます。
 
わずかなプログラミング/移植によって、これらの利点が得られます。
  
 
==  ALPS MCプログラム使用の第一歩  ==
 
==  ALPS MCプログラム使用の第一歩  ==
  
<!--'''Work in progress ... The tutorial is neither finished nor corrected ...Please send [[User:Fabien | me]] any comments / suggestions on this page '''-->
 
 
'''このチュートリアルは未完成です。コメント、ご提案があれば"comp-phys-alps-users@lists.comp-phys.org"までお願いします。'''
 
'''このチュートリアルは未完成です。コメント、ご提案があれば"comp-phys-alps-users@lists.comp-phys.org"までお願いします。'''
  
First of all, using the ALPS libraries implies that you use C++ as the programming language.
+
まず最初に、ALPSライブラリを使用するためにC++言語を使ってください。また、新しいMCアプリケーションの開発をおこなうが、使うべき内部データ構造やアルゴリズムは分かっているものと仮定します。
From now on, let us assume that you want to program a new MC application and that you already know what are going to be your internal data structure and the algorithm you will use for a single Monte Carlo step.
 
まず最初に、ALPSライブラリを使用するためにC++言語をプログラム言語としてください。今から、新しいMCアプリケーションの開発をおこない、シングルモンテカルロステップで使用される内部データ構造やアルゴリズムは分かっているものと仮定します。
 
  
<!--To use the ALPS libraries, you will need to create your own C++ class, that will be derived from an internal ALPS class. Let's call this class MyMonteCarlo and create a MyMonteCarlo.hpp header file.-->
+
ALPSライブラリを使うために、ALPSで定義されたクラスから継承した、自分のMC 用のクラスを定義します。今回はこのクラスをMyMonteCarloと呼び、MyMonteCarlo.hppヘッダーファイルに定義します。
ALPSライブラリを使うために、新しいC++クラスが必要です。このクラスは内部ALPSクラスとは分離されています。このクラスをMyMonteCarloと呼び、MyMonteCarlo.hppヘッダーファイルを生成してください。
 
  
 
   #ifndef MYMC_HPP
 
   #ifndef MYMC_HPP
Line 74: Line 65:
 
   #endif
 
   #endif
  
<!--We now see what all these lines mean.-->
+
各行が何を意味するか説明していきます。
各ラインが何を意味するか説明していきます。
 
<!--
 
*  First of all you need to include a few ALPS headers (some more will go here for other ALPS functionalities).
 
*  Then we will define our MyMonteCarlo class out by deriving it from a ALPS class. The above header file implies that you will use the MCRun ALPS class, which is the simplest one. If you want to enjoy the lattice functionalities of ALPS, replace the class definition line by:-->
 
  
 
* 最初に、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<>{
  
<!--and add in the headers-->
 
 
ヘッダーの追加もおこなってください。
 
ヘッダーの追加もおこなってください。
  
 
   #include <alps/lattice.h>
 
   #include <alps/lattice.h>
  
<!--If you moreover want to use the Model library (useful for lattice quantum models), use instead:-->
+
もし、さらにモデルライブラリ(格子量子モデル)を使用する場合は、次の様に置き換えてください。
もし、さらにモデルライブラリ(格子量子モデル)を使用する場合は、次の用に置き換えてください。
 
  
 
   class MyMonteCarlo : public alps::scheduler::LatticeModelMCRun<>{
 
   class MyMonteCarlo : public alps::scheduler::LatticeModelMCRun<>{
  
<!--*  In the public part, MyMonteCarlo(const alps::ProcessList&,const alps::Parameters&,int) is the constructor of your class, and will be needed to initialize all parameters.
+
* publicにある、<tt>MyMonteCarlo(const alps::ProcessList&,const alps::Parameters&,int)</tt>はコンストラクタです。そして、すべてのパラメータの初期化が必要でしょう。
* print_copyright(std::ostream&) is a simple function to output any useful information that you want to be output at the beginning of each simulation.
+
* <tt>print_copyright(std::ostream&)</tt>は、各シミュレーションの最初に、任意の情報を表示する関数です。
* The save and load functions are very useful functions where you will describe what is needed to save (load) on disk to restart the simulations after each checkpoint
+
* <tt>save</tt>,<tt>load</tt>は、各チェックポイントの後で再スタートするために、何がディスク上にsave(load)する必要があるか決定する関数です。
* The dostep function is your main MC function: this is the function that is going to be executed every MC step.
+
* <tt>dostep</tt>関数はMCの中心となる関数です。毎回のMCステップごとに実行されます。
* The is_thermalized function will tell the ALPS libraries when the thermalization part of your simulation is finished (that is, when can the measurement series start)
+
* <tt>is_thermalized</tt>は熱平衡化が終わっているかどうかをALPSライブラリに伝える関数です。
* The work_done function will tell the ALPS libraries what is the percentage of the simulations that is already done.-->
+
* <tt>work_done</tt>は、シミュレーションの何パーセントが実行済みかALPSライブラリに伝える関数です。 
* publicにある、MyMonteCarlo(const alps::ProcessList&,const alps::Parameters&,int)はコンストラクターです。そして、すべてのパラメータの初期化が必要でしょう。
 
* print_copyright(std::ostream&)は、各シミュレーションの最初の部分をアウトプットするかどうか設定する関数です。
 
* save,loadは、各チェックポイントの後で再スタートするために、何がディスク上にsave(load)する必要があるか決定する関数です。
 
* dostep関数はMC関数のメインです。あらゆるMDステップで実行されます。
 
* is_thermalizedは熱化のパートのシミュレーションがいつ終わったかALPSライブラリに教える関数です。
 
* work_doneは、シミュレーションの何パーセントが実行済みかALPSライブラリに教える関数です。 
 
  
<!--The rest of the job is now to correctly interface these functions with your program. This will be done in a file called, say, MyMonteCarlo.cpp-->
+
最後に、これらの関数を正しく呼びだすプログラムを、MyMonteCarlo.cppとして書きます。
最後に、これらの関数とプログラムを正しく結びつけるプログラム、MyMonteCarlo.cppを準備します。
 
  
<!--==  Building your own ALPS MC program ==
+
==  ALPS MCプログラムの作成 ==
===  The copyright function  ===-->
+
===  <tt>copyright</tt>関数 ===
==  ALPS MCプログラムのビルド  ==
 
===  copyright関数 ===
 
  
<!--We start with the easiest function print_copyright() in the file MyMonteCarlo.cpp-->
+
まず、MyMonteCarlo.cppの中で最も簡単な<tt>print_copyright()</tt>関数から始めます。
まず、MyMonteCarlo.cppの中で最も簡単なprint_copyright()関数から始めます。
 
  
 
   #include "MyMonteCarlo.hpp";
 
   #include "MyMonteCarlo.hpp";
Line 131: Line 106:
 
===  モンテカルロステップの制御  ===
 
===  モンテカルロステップの制御  ===
  
<!--Let us now concentrate on the management of MC steps. A typical situation is the following: one would like to perform a fixed number of steps for thermalization, then a fixed number of steps for the measurement part. Very often, one would like also to perform a certain amount of Monte Carlo steps between each measurement. Therefore it could be useful to define in your internal data structure the following variables (in MyMonteCarlo.hpp):-->
+
次に、MCステップについて説明します。典型的な例は次の通りです。まず、平衡化のためにある一定のステップ数だけ更新し、続いて、あらかじめ決めておいた回数だけ更新しながら物理量を測定します。普通、各測定の間に何回かのモンテカルロステップを実行します。これは、内部データ構造で、次の変数(in MyMonteCarlo.hpp)を設定することで実現できます。
次に、MCステップについて説明します。典型的な例は次の通りです。まず、熱化のためステップ数を決め、続いて、測定領域のステップ数を決めます。普通、各計測の間にモンテカルロステップを実行します。よって、内部データ構造で、次の変数(in MyMonteCarlo.hpp)を設定することで実行可能です。
 
  
 
   private :
 
   private :
Line 146: Line 120:
 
   };
 
   };
  
<!--Here Nb_Thermalisation_Steps will be the number of thermalization steps that you ask for and Nb_Steps the number of steps after thermalization that you ask for. Each_Measurement will be the number of steps between each measurement. These three numbers will be initialized later in the constructor. Steps_Done_Total will store the current number of MC finished steps (including those of thermalization). Finally Measurements_Done will store the intermediate number of steps done between each measurement. The do_update() and do_measurements() function (that you will have to define yourself) will perform respectively one single MC step and one series of measurement.-->
+
<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更新時および測定時に実行されます。
Nb_Thermalisation_Stepsは熱化ステップ数、Nb_Stepsは熱化後のMCステップ数です。Each_Measuremenは各測定のステップ数をあらわします。これらの3つの数字はコンストラクタで初期化されます。Steps_Done_TotalはMCが終わったステップの番号を保存します。最後に、Measurements_Done willは各測定の計算し終わった途中のステップ数を保存します。The do_update()とdo_measurements()関数はそれぞれ各一回のMCステップで実行されます。
 
  
<!--All these definitions lead to the following simple definitions of your class member functions in MyMonteCarlo.cpp-->
 
これらすべての定義は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); }
  
<!--This function will indeed return 1 if the current number of MC steps is superior to the total number of thermalization steps asked for , 0 otherwise. The second function-->
+
この関数は、現在のMCステップ数が平衡化ステップ数より大きいとき、<tt>true</tt>を返し、それ以外は<tt>false</tt>を返します。
この間数は、現在のMCステップ数が熱化ステップのトータル番号より大きいとき、1を返し、それ以外は0を返します。
 
  
 
   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.); }
  
<!--will return 0 if the simulation is not thermalized, and a number between 0 and 1 corresponding to the percentage of asked measurement steps already performed. Finally the dostep() function will look like this-->
+
シミュレーションが平衡化していなければ0を返し、そうでなければ測定ステップのうちどれだけが実行されたかを返します。最後に、<tt>dostep()</tt>関数は次のようになります。
シミュレーションが熱化しなければ0を返し、測定ステップがどれくらい実行されているかパーセンテージを与えます。最後に、dostep()関数は次のようになります。
 
  
 
   void MyMonteCarlo::dostep()
 
   void MyMonteCarlo::dostep()
Line 175: Line 144:
 
   }
 
   }
  
<!--At some point you have of course to define what your program really does during one MC step, and this will be done in the do_update() function. I can't help you with that one! The measurements have been grouped in our example in the do_measurements() function that will be described below.-->
+
もちろん、あなたのMC計算の、1回のMCステップの間に行われることは、あなた自身で定義しなければなりません。それを<tt>do_update()</tt> 関数の中に実装してください。
いくつかのポイントで、do_update()によっておこなわれる、MCステップ中に何をおこなうのか?ちゃんと調べなければならない。計測は例にあるdo_measurements()関数を参照してください。
+
測定は、後述する<tt>do_measurement()</tt>関数の中でまとめて行います。
  
 
===  セーブ、ロード関数  ===
 
===  セーブ、ロード関数  ===
  
<!--ALPS allows an easy treatment of the internal data to be checkpointed to disk. Let us imagine that in your internal data structure you need to checkpoint a few integers and an array of double to be able to restart your simulations-->
+
ALPSには計算中の内部データをディスクにチェックポイントとして生成する機能があります。今回は、チェックポイントを利用して計算を再スタートするために、整数変数と倍精度浮動小数点数の配列が必要になると仮定します。
ALPSには計算中の内部データをディスクにチェックポイントを生成する機能があります。チェックポイントほ利用して計算を再スタートするために、整数データと倍精度の配列が必要になります。
 
  
 
   private :
 
   private :
Line 191: Line 159:
 
   };
 
   };
  
<!--This can be accomplished very easily by writing -->
+
<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;}
  
<!--and the load function is easily guessed to be -->
+
<tt>load</tt>関数も対となる<tt>save</tt>から簡単に実装できます。
load関数は簡単に推測できます。
 
  
   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;}
  
<!--Note that you can dump this way most of the usual types (int,double,bool etc) and most standard containers are also available (such as vector or set). -->
+
ここで、ダンプの方法を説明します。一般的な型(<tt>int</tt>,<tt>double</tt>,<tt>bool</tt>など)や一般的なコンテナ(<tt>vector</tt>や<tt>set</tt>)が対応可能です。
ここで、ダンプの方法を説明します。一般的な型(int,double,boolなど)や一般的なコンテナ(vectorやset)が対応可能です。
 
  
<!--Now imagine that you have made your own little internal structure, -->
+
次のような構造体を定義したとします。
次のような内部構造を持っているとすると、
 
  
 
   struct Vertex
 
   struct Vertex
Line 214: Line 178:
 
     int SomeOtherVariable; }
 
     int SomeOtherVariable; }
  
<!--and you want to save an instantiation thereof in your Monte Carlo class.-->
+
この構造体のインスタンスを、自分のモンテカルロクラスの使って保存したいと考えると、
モンテカルロクラスでインスタンス化し保存したいと考えると、
 
  
 
   private :
 
   private :
Line 223: Line 186:
 
     };
 
     };
  
<!--Well, you just have to teach ALPS what to save and load in your structure-->
+
構造体の中で、何を保存、読み出しするのかをALPSに指示しなくてはいけません。
構造の中で、何を保存、ロードするのかをALPSに指示しなくてはいけません。
 
  
 
   alps::ODump& operator<<(alps::ODump& dump, const Vertex& v)
 
   alps::ODump& operator<<(alps::ODump& dump, const Vertex& v)
Line 232: Line 194:
 
   { return dump >> v.vertex_type >> v.coordinates;}
 
   { return dump >> v.vertex_type >> v.coordinates;}
  
<!--and then you'll easily be able to add MyVertex in the main ALPS save and load functions:-->
+
こうすることで、ALPSのsave,load関数に<tt>Vertex</tt>型の変数<tt>MyVertex</tt>を追加することが容易にできます。
そして、ALPSのsave,load関数のMyVertexを追加することが容易にできます。
 
  
 
   void MyMonteCarlo::save(alps::ODump& dump) const
 
   void MyMonteCarlo::save(alps::ODump& dump) const
 
     { dump <<  Number_of_Spins << MyOwnVariable << SpinArray << MyVertex;}
 
     { dump <<  Number_of_Spins << MyOwnVariable << SpinArray << MyVertex;}
  
<!--If you have used the management of Monte Carlo steps described above, you also want to add this in your save/load functions:-->
 
 
もし、上記のようにモンテカルロステップ数を設定したならば、save/load関数は次の用に加えることができます。
 
もし、上記のようにモンテカルロステップ数を設定したならば、save/load関数は次の用に加えることができます。
  
Line 247: Line 207:
 
===  do_measurements()関数 ===
 
===  do_measurements()関数 ===
  
<!--In this function you will perform your measurements, and give them to ALPS to be treated. This is pretty simple.-->
+
この関数では、物理量を測定し、ALPSに引渡します。
物理量の計測の実行方法です。次の例を参照してください。
 
  
 
   void MyMonteCarlo::do_measurements()
 
   void MyMonteCarlo::do_measurements()
Line 260: Line 219:
 
     }
 
     }
  
<!--and that's it? Now you might wonder: how does ALPS know what "Energy" or "Spin Correlations" is ? How does it distinguish between scalar measurements (such as Energy here) and vector ones (such as Correl) ? These two questions will be addressed below, in the Constructor of your class. -->
+
わかりますか?驚いたかもしれませんね。ALPSは "Energy"や"Spin Correlations"をどうやって知るのか?また、スカラー値(エネルギーなど)とベクター値(相関関数など)をどうやって区別するのか?この2つの疑問は、クラスのコンストラクタで以下の用に対処されます。
わかりますか?驚くかもしれませんが、ALPSは "Energy"や"Spin Correlations"をどうやって知るのか?また、スカラー値(エネルギーなど)とベクター値(相関)をどうやって区別するのか?この2つの疑問は、クラスのコンストラクタで以下の用に対処されます。
 
  
<!--Another question might be: why did you use a std::valarray and not a std::vector for the vector observable ? This is for internal ALPS reasons, but just remember that for vector observables, ALPS need the vectors to *always* be of the same size for each different measurements (in this example, measurements["Spin Correlations"] will fail if the Correl object has not always the same size -L here-).-->
+
他では、なぜベクター計測値にstd::vectorではなく、std::valarrayを使用しているのか?これはALPS内部の問題に起因しています。ALPSは各測定値が常に同じサイズであることを要請します。
他では、なぜベクター計測値にstd::vectorではなく、std::vectorを使用しているのか?これはALPS内部の問題に起因しています。ALPSは各測定値で常に同じサイズである必要があるからです。
 

Latest revision as of 12: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は各測定値が常に同じサイズであることを要請します。