2009年7月28日火曜日

Erlang 練習1

並列処理が得意な言語という事で Erlang というのを調べ始めたら、こんな良サイトを見つけた。→「Erlang World」 並列の手前まで読んだところで、ちょっとコードを書いてみた。最近使った数学の問題集でちょうどシンプソンの公式が出てきたので、これを Erlang で書いてみる。被積分関数は 4 / (1 + x^2) で、これを0から1まで積分するとπ(パイ)が出るが、2000等分のシンプソン法で近似値を求めるコードを以下のように書いた。
-module(simpson).
-export([integral/1]).

-define(Start, 0).
-define(End, 1).
-define(Steps, (1000 * 2)).

-define(DeltaX, ((?End - ?Start) / ?Steps)).
-define(XOf(Index), (?Start + Index * ?DeltaX)).

integral(F) ->
    sum(F) * ?DeltaX / 3.

sum(F) ->
    sum(F, ?Steps - 1, 4) + F(?XOf(?Steps)).
sum(F, Index, _) when Index == 0->
    F(?XOf(0));
sum(F, Index, M) ->
    sum(F, Index - 1, 6 - M) + M * F(?XOf(Index)).
結果は以下のような感じで、だいたいOK。
170> c(simpson).
{ok,simpson}
171> F = fun(X) -> 4 / (1 + math:pow(X, 2)) end.
#Fun<erl_eval.6.13229925>
172> simpson:integral(F).
3.1415926535897998
最初に書いたときは、ガードで分けた関数にたくさん重複コードを書いてしまっていたり、他にもかなりゴチャゴチャした汚いコードだったが、いろいろ調べて工夫してリファクタすると、少しはすっきりした。ちなみに新しい被積分関数 x^2 を渡すと以下のようになり、
174> F = fun(X) -> math:pow(X, 2) end.
#Fun<erl_eval.6.13229925>
175> simpson:integral(F).
0.3333333333333335
筆算で得られる値、1/3 に近い出力を得た。 並列が入ってないけど、最初だからこんなもんかな。次はまた同じシンプソンの公式をネタにして、両端の値の計、奇数項の値の計、偶数項の値の計をパラレルに計算して、合流したところで合算して h / 3 を掛けるようにしてみよう。まあ、まだ並列の辺りの解説は全然読んでいないので、そんな方針でいいのか判らないけど。あと Java と連携できるのかも調べてみたい。

0 件のコメント:

コメントを投稿