読者です 読者をやめる 読者になる 読者になる

倭算数理研究所

科学・数学・学習関連の記事を、「倭マン日記」とは別に書いていくのだ!

2.4 True BASIC のプログラム series (Groops)

計算物理学入門 シミュレーション

さて、最近は 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()

出力されるグラフは以下のようになります:


和を繰り返すと、だんだん一定の値に近づいていくのが分かりますね。

追記

ちなみに、ここで計算した級数の極限
  
の値は
  
になります。 これはリーマンの ζ 関数
  
を使って ζ(2) と書かれることが多いですね。 値の導出方法はこちらを参照。
計算物理学入門

計算物理学入門

  • 作者: ハーベイゴールド,ジャントボチニク,Harvey Gould,Jan Tobochnik,鈴木増雄,石川正勝,溜渕継博,宮島佐介
  • 出版社/メーカー: ピアソンエデュケーション
  • 発売日: 2000/12
  • メディア: 単行本
  • 購入: 1人 クリック: 28回
  • この商品を含むブログ (45件) を見る