今回は連分数を実装する ContinuedFraction クラス(一覧)。
ContinuedFraction クラスを使用する場合は、サブクラスもしくは無名クラスによって抽象メソッド getA(), getB() の実装を行う必要がありました(こちら参照)。 Java ではそれで仕方ありませんでしたが、Groovy では処理をオブジェクトとして扱えるクロージャがサポートされているので、これらから ContinuedFraction オブジェクトを生成できるようにしてみます。
ClosureContinuedFraction クラス
まずは Groovy のクロージャ (groovy.lang.Closure) を連分数の評価に使う、ContinuedFraction のサブクラスを定義します:
import groovy.lang.Closure; import org.apache.commons.math.util.ContinuedFraction; class ClosureContinuedFraction extends ContinuedFraction{ private Closure a, b; public ClosureContinuedFraction(){} public ClosureContinuedFraction(Closure a, Closure b){ this(); this.a = a; this.b = b; } public Closure getA() { return a; public void setA(Closure a) { this.a = a; } public Closure getB() { return b; } public void setB(Closure b) { this.b = b; } @Override protected double getA(int i, double v) { return (Double)this.a.call(new Object[]{i, v}); } @Override protected double getB(int i, double v) { return (Double)this.b.call(new Object[]{i, v}); } }
これは Java クラスとして実装しています。
拡張
上記の ClosureContinuedFraction クラスを踏まえて、2つのクロージャから ContinuedFraction オブジェクトを生成する create() メソッドを ContinuedFraction クラスの static メソッドとして定義しましょう:
ContinuedFraction.metaClass.'static'.create = { Closure a, Closure b -> return new ClosureContinuedFraction(a, b) }
まぁ、何てことないですね。
使用方法
追加した create() メソッドは以下のようにして使います:
@GrabResolver('http://www5.ocn.ne.jp/~coast/repo/') @Grab('org.waman.math:wamans-math:0.0.1') WamansMath.enhance(CommonsMathPackage.UTIL) def a = { int n, double x -> (n == 0) ? 3d : 6d } def b = { int n, double x -> double y = (2d * n) - 1d; y*y } def frac = ContinuedFraction.create(a, b) frac.evaluate(0d, 0.0000001d)
パフォーマンスは Pure Java に比べて10分の1くらいになってしまいますが・・・
- 作者: 奥村晴彦,杉浦方紀,津留和生,首藤一幸,土村展之
- 出版社/メーカー: 技術評論社
- 発売日: 2003/05
- メディア: 単行本
- 購入: 2人 クリック: 44回
- この商品を含むブログ (58件) を見る