|
2.13.12 外部プログラム中で式を処理する
Mathematicaの式はすべての種類のデータを扱うことができる,非常に一般的な方法を提供している が,その式を外部プログラム中で利用したいこともあるだろう. しかし,Cのような言語は通常のMathematicaの式を保持する直接的な方法がないが, MathLinkライブラリが提供するループバックリンクを利用すれば可能になる. ループバックリンクとは外部プログラム内部のローカルな MathLinkコネクションで,そのリンクに式を書き込んで,あとでその式を読み戻すことが可能である.

ループバックリンク関数
...
ループバックリンクを開く.
ml = MLLoopbackOpen(stdenv, &errno);
式 Power[x, 3]をリンクにおく.
MLPutFunction(ml, "Power", 2);
MLPutSymbol(ml, "x");
MLPutInteger(ml, 3);
...
ループバックリンクから式を取り出す.
MLGetFunction(ml, &head, &n);
MLGetSymbol(ml, &sname);
MLGetInteger(ml, &k);
...
ループバックリンクを再度閉じる.
MLClose(ml);
MLTransferExpression()を使って Mathematicaから stdlinkを経由して式を取り出すことができる.取り出した式はループバックリンクに保存し,あとで処理することもできる.
MLTransferExpression()はまた,ループバックリンクにためておいた式を取り出し,それを stdlink 経由で Mathematicaに転送することもできる.
...
21!をループバックリンクにおく.
MLPutFunction(ml, "Factorial", 1);
MLPutInteger(ml, 21);
頭部 FactorIntegerを Mathematicaに送信する.
MLPutFunction(stdlink, "FactorInteger", 1);
ループバックリンクにある 21!を stdlinkに転送する.
MLTransferExpression(stdlink, ml);
ループバックリンクにはあらゆる式の列をおくことができる.式をおいた順番と式を取り出す順番は通常,同じになる.
普通は取り出した式はリンク上には残っていない.しかし,MLCreateMark()を使えば,リンク上の式のシーケンスの特定の位置にマークすることができる. MathLinkが式を保存するときはいつもそのマークの後ろに保存させることができ,それを後で取り出すことができる.

MathLinkリンクにマークする
...
整数 45をループバックリンクにおく.
MLPutInteger(ml, 45);
33をリンクにおく.
MLPutInteger(ml, 33);
76をリンクにおく.
MLPutInteger(ml, 76);
リンクから 45を読み出す. 45はリンク上には残っていない.
MLGetInteger(ml, &i);
リンク上の現在地をマークする.
mark = MLCreateMark(ml);
33が読み出される.
MLGetInteger(ml, &i);
76が読み出される.
MLGetInteger(ml, &i);
マークの位置に戻る.
MLSeekMark(ml, mark, 0);
33が再び読み出される.
MLGetInteger(ml, &i);
マークは利用がすんだら破壊する.不必要な式は残っていない.
MLDestroyMark(ml, mark);
MathLinkライブラリは,ループバックリンクの開閉が非常に効果的に行えるように実装されている.ひとつだけ頭にいれておくべきことは,あるリンク上にマークを生成すると,MathLinkは,マークが破壊されるまで,その後リンクにおかれる式を記憶することである.

リンクから式の一部を取得する関数

MLGetNext()が返す定数
switch(MLGetNext(ml)) {
合成関数を読み込む.
case MLTKFUNC:
MLGetArgCount(ml, &n);
頭部で回帰
for (i = 0; i < n; i++)
各引数で回帰

...
シンボルを読み込む.
case MLTKSYM:
MLGetSymbol(ml, &name);
...
整数を読み込む.
case MLTKINT:
MLGetInteger(ml, &i);
...
}
MLGetNext()を使うことで,あらゆる式を読み込むプログラムを書くことは簡単になる. MathLinkの動作に従い,関数の頭部と引数とは,リンク上の連続した式として現れ,それらを1個ずつ読み込むことができる.
関数の頭部がシンボルであることが分かったら,MLGetNext()の代りに MLGetFunction()を使うことができる.しかし,この場合,そのシンボル名を保持するために使ったメモリを MLDisownSymbol()を呼び出して解放することを忘れないこと.

リンクに式の一部をおく関数
MLGetNext()の場合と同じように,MLPutNext()の指定ではヘッダファイル mathlink.hに定義してある MLTKFUNC 等のデフォルトの識別子を使い式の型の指定を行う.
|