Location : Home > Languages > Perl > Package
Title : Math::SymbolicX::Inline
Toolbox Logo

名称

 Math::SymbolicX::Inline - Math::Symbolic のインライン関数


概要

use Math::SymbolicX::Inline <<'END';

foo = x * bar
bar = partial_derivative(x^2, x)
x (:=) arg0 + 1
END

print bar(3);
# 2*(3+1) である '8' を出力する。...

print foo(3);
# 2*(3+1)*(3+1) である '32' を出力する。

print x(3);
# 演算子の周囲の括弧は x の範囲を特定してくれる。

説明

 本モジュールは Math::Symbolic の拡張である。そのモジュールが要請する基本的な親和性を保っている。
 Math::SymbolicX::Inline は Math::Symbolic の文脈における記号式から Perl 関数を生成する。これにより任意の Math::Symbolic ツリー(微分を含む)を生成し、パッケージサブルーチンとしてコンパイルすることができる。
 Math::Symbolic における式の標準ではない文法的要素があるが、例を使ったほうが説明しやすい。下記の簡単な例における議論を参照して欲しい。

エクスポート

 本モジュールはいかなる関数もエクスポートしないが、ユーザの現在の名前空間における関数を生成することを意図している。

簡単な例

 サインの2乗の微分を計算する関数を生成する不自然な例を示す。 sin(x)*sin(x) の x に関する微分は 2*sin(x)*cos(x) であることは数学的に自分で計算できるかもしれない。しかし後に関数を変更したくなるかも知れないし、微分が非常に複雑だと思っているかも知れないし、単に面倒くさくなるかも知れない。そのときは次のように書けばよい。

use Math::SymbolicX::Inline <<'HERE';

myfunction = partial_derivative( sin(arg0) * sin(arg0), arg0 )

HERE

 その後で Perl から適切な名前付けられた関数を用いればよい。これは Math::Symbolic ツリーを Perl コードにコンパイルしているので手で計算するのと比べてほとんどパフォーマンスは落ちないだろう。(どんなに面倒くさくても Math::Symbolic::Custom::CCompiler を用いて C でコンパイルすること。)

print myfunction(2);

 結果 -0.756802495307928 を出力する。

拡張した使用法

 上の例で arg0 変数の用い方に気づいたかも知れない。argX は関数の X + 1 番目の変数を参照している。したがって arg19 は20番目の引数である。
 しかし数学的な表記では変数として arg0 を用いるのは典型的でない。sin(x*y)*sin(x*y) の x に関する微分を求めるには x 及び y を用いたい。それにサインとコサインを可能な限り小さい努力で入れ替えたい。これは以下のように実装する。

my $function = 'sin';

use Math::SymbolicX::Inline <<HERE;

# 関数の定義
myfunction = partial_derivative(inner, x)

# 宣言の支援
inner (=) $function(x*y)^2
x (:=) arg0
y (:=) arg1

HERE

 コードには3種類の記号の宣言が追加されている。これらの新しい定義はすべて括弧の中に入れられた演算子の割り当てであって、エクスポートするためではない。これは後に inner(2, 3) という形で用いることはできないということを意味する。しかしmyfunction(2, 3) という呼び出しは可能である。変数 $function は HERE ドキュメントに挿入される。Perl のマニュアルページにはこの種の引用に関する説明がある。
 宣言において空白には意味がない。必要なのは割り当てる演算子を新しい行に書くことである。何行あろうと関係はない。
 以下の式は妥当なものである。

myfunction =
             partial_derivative(
                                 inner, x
                               )
inner (=) $function(x*y)^2
...

 けれども次は妥当ではない。

myfunction
= partial_derivative(inner, x)
...

 宣言の順序は重要でないことに注意することは重要である。

x (:=) arg0
...
myfunction = partial_derivative(inner, x)

と書いても同じ結果を得る。
 Perl コードから宣言された関数がアクセス可能とするために割り当てる演算子の周りの括弧を取ることもできる。
 x と y の宣言における := 演算子には戸惑ったかも知れない。この演算子は微分の文脈でのみ面白い。例えば関数 inner の x 微分を計算したいとしよう。厳密に言えばその微分は 0 である! なぜなら微分しようとしている項(inner)は −厳密に言えば− x を含んでいないからである。inner の関数の定義はそれを微分する前に置かれるべきである。それゆえに、一般的には、関数の定義は微分前に行うほうがよい。
 さて、他にも問題はある。置き換えに arg0 を用いると同じ x が発生し微分できなくなる。それこそが := 演算子を導入した理由である。これは全ての微分に適用した後に関数を置き換える。このため x のような後で置き換える関数の定義では inner のような標準的な関数を参照することができない。

最後のビット

 Math::SymbolicX::Inline への宣言ブロックにない関数のあらゆる呼び出しは現在のパッケージにおけるサブルーチン呼び出しとして解決される。サブルーチンがなければモジュールはスタックバックとレースとともにエラーを出力する。


参考資料

 本モジュールの最新のバージョンは http://steffen-mueller.net または CPAN で入手可能である。
 Math::Symbolic, Math::Symbolic::Compiler, Math::Symbolic::Custom::CCompiler
 本モジュールはモジュールの Inline:: 階層にはないため、モジュールを利用していない。にもかかわらず類似のモジュールが Inline 階層にある。


著者

 Steffen Muler, <symbolic-module at steffen-mueller dot net>


著作権とライセンス

 Copyright (C) 2005 by Steffen Muler

 本ライブラリはフリーソフトウェアであり、Perl 本体と同等の条件で修正/再配布してもよい。Perl 5.8.4、利用者の選択によっては Perl 5以降の入手可能なバージョンで利用可能である。

Toolbox Logo
Updated : 2007/05/13