さて、最近は Groovy の使い方の解説ばかりだったので、少しは Groops を使ったサンプルも書いておきましょう。 ってことで、今回は前回に見たプログラム「series」を Groops で書いてみます。
物理系をクラスで書いたサンプル
まずは今までの記事で書いたことを元にした Groops のシミュレーション・コード。@GrabResolver('https://github.com/waman/groops-core/tree/master/repo') @Grab('org.waman.groops:groops-core:0.1-beta') import org.waman.groops.builder.SimulationBuilder import org.waman.groops.simulation.annotation.system.* new SimulationBuilder().simulation{ system(new SeriesSystem()) init(n:0, sum:0d) count(total:100) console() }.simulate() class SeriesSystem extends AnnotationObservableSystem{ @State int n @State double sum @Override void evolve(Map<String, Object> params) { this.n++ this.sum += 1d/(n*n) } }
- series.groovy
- @GrabResolver, @Grape アノテーションは Groops の Jar ファイルを取得するおまじない。
- SimulationBuilder オブジェクトに対して呼び出している simulation ノードがシミュレーションを構築します。
- simulation ノードで生成された Simulator オブジェクトに対して、simulate() メソッドを呼び出して直接 シミュレーションを実行しています。
- SeriesSystem クラスは物理系を表すクラス。 AbstractObservableSystem を拡張して作成しています。
ちなみに、Groops 0.1-beta では Java SE 7, Groovy 2.0-beta-2 が必要です。 Groops の Jar ファイルが必要ならこちらからダウンロードできます:
グラフを出力するには、別途 JFeeChart とそれに必要なライブラリが必要です。
簡単な物理系はノードで構築
今回のシミュレーションでは物理系がかなり単純なので(そもそも物理系でもないけど)、いちいちクラスを作成するのも大仰な感じがします。 なので、物理系もノードで構築してみましょう。 上記のコードは以下のように書き換えられます:@GrabResolver('https://github.com/waman/groops-core/tree/master/repo') @Grab('org.waman.groops:groops-core:0.1-beta') import org.waman.groops.builder.SimulationBuilder new SimulationBuilder().simulation{ observableSystem{ dominants = [n:0, sum:0d] evolve = { system, Map params -> system.n++ system.sum += 1d/(system.n*system.n) } } count(total:100) console() }.simulate()
- observableSystem ノードによって AbstractObservableSystem クラスのサブクラスを作成することができます。 詳しい説明は省略。
import 文なども結構減ってスッキリ! でも、ライブラリ取得のコードを除いても、元の True BASIC や Groovy コードよりかなり長くなってしまってますね(^ ^;) まぁ、仕方なし。
グラフを出力する
せっかくシミュレーションを実行するなら、結果をグラフで出力した方がいいよね、ってことでグラフを出力するコードを追加。@GrabResolver('https://github.com/waman/groops-core/tree/master/repo') @Grab('org.waman.groops:groops-core:0.1-beta') import org.waman.groops.builder.SimulationBuilder import java.awt.Color new SimulationBuilder().simulation{ observableSystem{ dominants = [n:0, sum:0d] evolve = { system, Map params -> system.n++ system.sum += 1d/(system.n*system.n) } } count(total:100) console() png(fileName:'chart.png', overwrite:true){ chart(title:'series'){ point(label:'Simulation', x:'n', y:'sum') marker(label:'pi^2/6', y:Math.PI**2/6d, color:Color.BLUE) } } }.simulate()
- seriesWithChart.groovy
- png ノードの使い方はこちらを参照。
出力されるグラフは以下のようになります:
和を繰り返すと、だんだん一定の値に近づいていくのが分かりますね。
追記
ちなみに、ここで計算した級数の極限の値は
になります。 これはリーマンの ζ 関数
を使って ζ(2) と書かれることが多いですね。 値の導出方法はこちらを参照。
- 作者: ハーベイゴールド,ジャントボチニク,Harvey Gould,Jan Tobochnik,鈴木増雄,石川正勝,溜渕継博,宮島佐介
- 出版社/メーカー: ピアソンエデュケーション
- 発売日: 2000/12
- メディア: 単行本
- 購入: 1人 クリック: 28回
- この商品を含むブログ (45件) を見る