外部プログラムをMathematica から呼び出す
外部プログラム中に定義してある関数を
Mathematica から呼び出すためには,関数に引数を渡したり,関数の結果を
Mathematica に戻すためのコードを外部プログラムに追加する必要がある.
簡単なものなら,呼び出したい外部関数ごとに適切な
MathLink テンプレートを用意するだけで必要なコードを生成することができる.
:Begin:
:Function: f
:Pattern: f[x_Integer, y_Integer]
:Arguments: {x, y}
:ArgumentTypes: {Integer, Integer}
:ReturnType: Integer
:End:
外部関数fに対応するMathLink テンプレートを含むf.tmファイル
| :Begin: | 特定の関数に関するテンプレートを開始する |
| :Function: | 外部プログラム中の関数名 |
| :Pattern: | 関数を呼び出すように定義されたパターン |
| :Arguments: | 関数に渡す引数 |
| :ArgumentTypes: | 関数に渡す引数の型 |
| :ReturnType: | 関数の戻り値の型 |
| :End: | ひとつの関数に関するテンプレートを終了する |
| :Evaluate: | 関数をインストールする際に評価されるMathematica 式 |
MathLink テンプレートの要素
外部関数に対応する
MathLink テンプレートは関数のソースコードと結合させる必要がある.ソースコードがC言語で書かれていると仮定すると,それは単に
MathLink のヘッダファイルを含むコード1行と小さい
mainプログラムをソースコードに追加するだけで済む.
int f(int x, int y) { return x+y; }
|
外部関数を Mathematica からの呼出しに答えるように設定する.
int main(int argc, char *argv[]) { return MLMain(argc, argv); }
|
C言語のソースを含んでいるf.cファイル
システムによっては,
main関数の形式が若干異なることもある.詳しくは
MathLink デベロッパーキット中のリリースノートを参照すること.
| mcc | MathLink ソースファイルを前処理し,コンパイルする |
| mprep | MathLink のソースファイルを前処理する |
MathLink ソースファイルを処理する外部プログラム
MathLink テンプレートは通常
file.tmという名前のファイルにする.そのファイルにはさまざまな関数のテンプレートに混ざって,Cのソースコードも挿入することができる.
適当なファイルを準備したら,
MathLink テンプレートに書き込まれた情報とともに,ソースコードをコンパイルする.コンパイルは外部プログラムで行うが,細かい部分はコンピュータシステムによって違っている.
Unixを例に取ると,
MathLink デベロッパーキットには
mccと呼ばれるプログラムがあり,このプログラムは名前が
.tmで終る
MathLink テンプレートファイルを前処理してCのソースコードを生成し,そのソースコードを
ccでコンパイルする.
mccはコマンドラインオプションや他のファイルは直接
ccに渡す.
f.tmを前処理して得られるCのソースファイルを f.cファイルとともにコンパイルする. |
Mathematica にバイナリをインストールする.
| Out[1]= |  |
|
f[x, y]は整数の和を求める外部関数 f(intx, inty)を呼び出す.
| Out[2]= |  |
|
外部プログラムはマシンサイズの整数しか扱えないため,妙なことが起っている.
| Out[3]= |  |
|
Windowsでは,
MathLink デベロッパーキットには,
mprepプログラムが入っていて,これを直接呼び出して,前処理したい
.tmファイルを処理する.
mprepはCのソースコードを出力するので,それをCコンパイラにかける.
外部プログラムへのリンクの取扱い
| Out[4]= |  |
|
これはリンクを使って評価できる Mathematica のパターンを示している.
| Out[5]= |  |
|
Installは適切な関数 ExternalCallを実行する実際の関数 fを設定する. |
MathLink テンプレートが処理されるとき,基本的に2つのことが行われる.まず,
:Pattern:と
:Arguments:の仕様に従い,
MathLink 経由で外部プログラムを呼び出す
Mathematica の定義を生成する.次に,
:Function:,
:ArgumentTypes:と
:ReturnType:の仕様に従って外部プログラム中の関数を呼び出すCのソースコードが生成される.
定義が設定されるべき Mathematica のパターン.
:Pattern: SkewAdd[x_Integer, y_Integer:1]
|
リスト中の2つの要素の値が外部関数の実引数となる.
:Arguments: {x, If[x > 1, y, y + x - 2]}
|
:ArgumentTypes: {Integer, Integer}
|
MathLink テンプレート中の
:Pattern:と
:Arguments:には,どんな
MathLinkの式を与えても構わない.
:Arguments:に与えたものはすべて,その外部関数の呼出しごとに毎回評価される.評価の結果は引数のリストとして関数に渡される.
外部関数の呼出し時ではなく,インストール時にだけ,評価させたい
Mathematica 式もあるだろう.
その場合,
MathLinkテンプレート中の
:Evaluate:を利用する.
:Evaluate:の後ろに与える式は何行になっても構わない.空行,あるいはスペース文字やタブ文字で始まらない行がきたら,式が終ったとみなされる.
SkewAddの使用法は外部関数がインストールされるときに設定される.
:Evaluate: SkewAdd::usage = "SkewAdd[x, y] performs a skew addition in an external program."
|
外部プログラムがインストールされるときは,
MathLink テンプレートファイルに記述された順に仕様が読み込まれる.
:Begin:より前の
:Evaluate:に与えられた式は外部関数の定義が読み込まれる前に評価される.
外部関数の定義が読み込まれる以前に評価される Mathematica の式.
:Evaluate: BeginPackage["XPack`"] :Evaluate: XF1::usage = "XF1[x, y]は1つの外部関数です." :Evaluate: XF2::usage = "XF2[x]は他の外部関数です." :Evaluate: Begin["`Private`"]
|
Mathematica の関数 XF1が外部Cプログラム中の関数 fを呼び出すように設定される.
:Begin: :Function: f :Pattern: XF1[x_Integer, y_Integer] :Arguments: {x, y} :ArgumentTypes: {Integer, Integer} :ReturnType: Integer :End:
|
Mathematica の関数 XF2は gを呼び出す.その引数と戻り値は近似された実数である.
:Begin: :Function: g :Pattern: XF2[x_?NumberQ] :Arguments: {x} :ArgumentTypes: {Real} :ReturnType: Real :End:
|
外部関数の定義の後に評価される Mathematica 式.これらは関数定義に用いた特別なコンテキストを終了する.
:Evaluate: End[ ] :Evaluate: EndPackage[ ]
|
関数 fのソースコード.引数の名前は対応する Mathematica のものと一致する必要はない.
int f(int i, int j) { return i + j; }
|
関数 gのソースコード. Mathematica 中で与えた数は, gに渡される前にCの doubleに変換される.
double g(double x) { return x*x; }
|
:Evaluate:を利用して,外部プログラムが最初にインストールされるときに評価される
Mathematica の式を指定することができる.また,外部プログラムの
main()中の
MLMain()呼出しの前に挿入したコードも,外部プログラムのインストール前に実行される.外部関数が実行される前に,外部プログラムを初期化する場合等に使うとよいだろう.
外部プログラムからMathematica のコマンドを実行する
もし i<jであれば Mathematica の Printを評価する.
if (i < j) MLEvaluateString(stdlink, "Print[\"negative\"]"); return i - j; }
|
上で定義した diff関数を含むプログラムをインストールする.
| Out[7]= |  |
|
| Out[8]= |  |
|
MLEvaluateString()の評価結果は,どんなものであろうと単に無視されることに注意すること.戻り値の利用には
Mathematica と外部プログラムとの間で完全な双方向の通信が必要になる.これに関しては
「外部プログラムとの双方向通信」で述べる.