version 1.9, 2005/07/20 16:24:56 |
version 1.10, 2015/05/25 07:13:52 |
|
|
%#!platex |
%#!platex |
%% $OpenXM: OpenXM/src/ox_math/documents/ox_math.tex,v 1.8 2005/07/19 15:58:37 ohara Exp $ |
%% $OpenXM: OpenXM/src/ox_math/documents/ox_math.tex,v 1.9 2005/07/20 16:24:56 ohara Exp $ |
|
|
\documentclass{jarticle} |
\documentclass{jarticle} |
\title{Mathematica の Open XM 化について |
\title{Mathematica $B$N(B Open XM $B2=$K$D$$$F(B |
% \\ {\small --- Open Mathematica サーバの内部構成 ---} |
% \\ {\small --- Open Mathematica $B%5!<%P$NFbIt9=@.(B ---} |
} |
} |
\date{ |
\date{ |
%January 19, 1999 |
%January 19, 1999 |
|
|
November 25, 1999 |
November 25, 1999 |
(Revised July 20, 2005) |
(Revised July 20, 2005) |
} |
} |
\author{小原功任} |
\author{$B>.868yG$(B} |
|
|
\def\oxmath{{\tt ox\_math}} |
\def\oxmath{{\tt ox\_math}} |
|
|
\begin{document} |
\begin{document} |
\maketitle |
\maketitle |
|
|
\section{我々が提供するもの} |
\section{$B2f!9$,Ds6!$9$k$b$N(B} |
|
|
我々が提供するのは二つのプログラムとそのソースである。一つ目は |
$B2f!9$,Ds6!$9$k$N$OFs$D$N%W%m%0%i%`$H$=$N%=!<%9$G$"$k!#0l$DL\$O(B |
\oxmath プログラムであり、これは OpenXM サーバの一種である。二つ目は |
\oxmath $B%W%m%0%i%`$G$"$j!"$3$l$O(B OpenXM $B%5!<%P$N0l<o$G$"$k!#Fs$DL\$O(B |
{\tt math2ox} であり、OpenXM クライアントである。 |
{\tt math2ox} $B$G$"$j!"(BOpenXM $B%/%i%$%"%s%H$G$"$k!#(B |
|
|
動作環境は Solaris, Linux および Windows、対象としている Mathematica の |
$BF0:n4D6-$O(B Solaris, Linux $B$*$h$S(B Windows$B!"BP>]$H$7$F$$$k(B Mathematica $B$N(B |
バージョンは、3.0 〜 4.2 までである。バージョン 5.x については、我々が所 |
$B%P!<%8%g%s$O!"(B3.0 $B!A(B 4.2 $B$^$G$G$"$k!#%P!<%8%g%s(B 5.x $B$K$D$$$F$O!"2f!9$,=j(B |
有していないため調査していない。 |
$BM-$7$F$$$J$$$?$aD4::$7$F$$$J$$!#(B |
|
|
Windows 上では \oxmath は、cygwin のもとで動作する。\oxmath の Windows |
Windows $B>e$G$O(B \oxmath $B$O!"(Bcygwin $B$N$b$H$GF0:n$9$k!#(B\oxmath $B$N(B Windows |
対応は藤本さんによる(2002年4月)。ありがとう。 |
$BBP1~$OF#K\$5$s$K$h$k(B(2002$BG/(B4$B7n(B)$B!#$"$j$,$H$&!#(B |
|
|
\section{Open Mathematica サーバの構成} |
\section{Open Mathematica $B%5!<%P$N9=@.(B} |
|
|
Open Mathmatica サーバ(\oxmath)はOpen XM クライアントおよび Mathematica |
Open Mathmatica $B%5!<%P(B(\oxmath)$B$O(BOpen XM $B%/%i%$%"%s%H$*$h$S(B Mathematica |
Kernel と通信する。\oxmath は起動直後に Mathematica Kernel を起動し、 |
Kernel $B$HDL?.$9$k!#(B\oxmath $B$O5/F0D>8e$K(B Mathematica Kernel $B$r5/F0$7!"(B |
Mathematica Kernel と協調して動作する。Mathematica Kernel とは MathLink |
Mathematica Kernel $B$H6(D4$7$FF0:n$9$k!#(BMathematica Kernel $B$H$O(B MathLink |
ライブラリを利用して通信する。つまり \oxmath は MathLink |
$B%i%$%V%i%j$rMxMQ$7$FDL?.$9$k!#$D$^$j(B \oxmath $B$O(B MathLink |
のラッパだと思ってよい。Open XM クライアントとの間はソケットを利用して通 |
$B$N%i%C%Q$@$H;W$C$F$h$$!#(BOpen XM $B%/%i%$%"%s%H$H$N4V$O%=%1%C%H$rMxMQ$7$FDL(B |
信する。\oxmath はファイルディスクリプタ 3,4 が既にオープ |
$B?.$9$k!#(B\oxmath $B$O%U%!%$%k%G%#%9%/%j%W%?(B 3,4 $B$,4{$K%*!<%W(B |
ンされていると思って, 3 から読み込み、4 に書き出す。 |
$B%s$5$l$F$$$k$H;W$C$F(B, 3 $B$+$iFI$_9~$_!"(B4 $B$K=q$-=P$9!#(B |
|
|
さらに \oxmath には計算中断機能が必要であるが、この機能は 2003年のはじめに実装された。 |
$B$5$i$K(B \oxmath $B$K$O7W;;CfCG5!G=$,I,MW$G$"$k$,!"$3$N5!G=$O(B 2003$BG/$N$O$8$a$K<BAu$5$l$?!#(B |
|
|
次に、Open XM 規約より \oxmath はスタックマシンでなければならない。 |
$B<!$K!"(BOpen XM $B5,Ls$h$j(B \oxmath $B$O%9%?%C%/%^%7%s$G$J$1$l$P$J$i$J$$!#(B |
スタックのオブジェクトは cmo 型の変数、あるいはその派生クラスである. |
$B%9%?%C%/$N%*%V%8%'%/%H$O(B cmo $B7?$NJQ?t!"$"$k$$$O$=$NGI@8%/%i%9$G$"$k(B. |
つまり、Open XM 規約で定められたデータ形式を流用している. |
$B$D$^$j!"(BOpen XM $B5,Ls$GDj$a$i$l$?%G!<%?7A<0$rN.MQ$7$F$$$k(B. |
この方法の利点は Open XM プロトコルを通して通信するにあたって |
$B$3$NJ}K!$NMxE@$O(B Open XM $B%W%m%H%3%k$rDL$7$FDL?.$9$k$K$"$?$C$F(B |
特にデータの変換を必要としないことである. すなわちCMO の各データタイプ |
$BFC$K%G!<%?$NJQ49$rI,MW$H$7$J$$$3$H$G$"$k(B. $B$9$J$o$A(BCMO $B$N3F%G!<%?%?%$%W(B |
は \oxmath の内部でも, CMO として保持する |
$B$O(B \oxmath $B$NFbIt$G$b(B, CMO $B$H$7$FJ];}$9$k(B |
わけである. |
$B$o$1$G$"$k(B. |
|
|
サーバの各関数は cmo* を受け取り、タグをみて実際のクラスが何であるかを |
$B%5!<%P$N3F4X?t$O(B cmo* $B$r<u$1<h$j!"%?%0$r$_$F<B:]$N%/%i%9$,2?$G$"$k$+$r(B |
知り、動作を決定する. |
$BCN$j!"F0:n$r7hDj$9$k(B. |
|
|
現在、実装されているスタックマシン命令は |
$B8=:_!"<BAu$5$l$F$$$k%9%?%C%/%^%7%sL?Na$O(B |
SM\_popCMO, SM\_popString, SM\_pops, SM\_executeFunction, |
SM\_popCMO, SM\_popString, SM\_pops, SM\_executeFunction, |
SM\_executeStringByLocalParser, SM\_mathcap, SM\_setMathcap(受け取るだけ |
SM\_executeStringByLocalParser, SM\_mathcap, SM\_setMathcap($B<u$1<h$k$@$1(B |
で何もしない)である。 |
$B$G2?$b$7$J$$(B)$B$G$"$k!#(B |
|
|
\section{MathLink プログラミングと \oxmath} |
\section{MathLink $B%W%m%0%i%_%s%0$H(B \oxmath} |
|
|
最初に、MathLink プログラミングについての基礎的事項を説明し、 |
$B:G=i$K!"(BMathLink $B%W%m%0%i%_%s%0$K$D$$$F$N4pACE*;v9`$r@bL@$7!"(B |
次に \oxmath の Mathematica Kernel との通信部分について述べる。 |
$B<!$K(B \oxmath $B$N(B Mathematica Kernel $B$H$NDL?.ItJ,$K$D$$$F=R$Y$k!#(B |
|
|
MathLink プログラミングについては、概ね、Mathematica |
MathLink $B%W%m%0%i%_%s%0$K$D$$$F$O!"35$M!"(BMathematica |
Book~\cite{Wolfram-1996} や宮地~\cite{miyachi-1998} などを参照すればよい |
Book~\cite{Wolfram-1996} $B$d5\CO(B~\cite{miyachi-1998} $B$J$I$r;2>H$9$l$P$h$$(B |
が、必ずしもこれらの書籍に明確に書かれているわけではない(探せば見つかる |
$B$,!"I,$:$7$b$3$l$i$N=q@R$KL@3N$K=q$+$l$F$$$k$o$1$G$O$J$$(B($BC5$;$P8+$D$+$k(B |
が)。 |
$B$,(B)$B!#(B |
|
|
まず MathLink とは、Wolfram が提供するライブラリであり、Mathematica のネッ |
$B$^$:(B MathLink $B$H$O!"(BWolfram $B$,Ds6!$9$k%i%$%V%i%j$G$"$j!"(BMathematica $B$N%M%C(B |
トワーク対応部分に相当する。Mathematica Kernel と通信するプログラムを書 |
$B%H%o!<%/BP1~ItJ,$KAjEv$9$k!#(BMathematica Kernel $B$HDL?.$9$k%W%m%0%i%`$r=q(B |
こうとするならば、MathLink を利用する必要がある。MathLink の内部構成は明 |
$B$3$&$H$9$k$J$i$P!"(BMathLink $B$rMxMQ$9$kI,MW$,$"$k!#(BMathLink $B$NFbIt9=@.$OL@(B |
らかにされていないが、{\bf 大部分はネットワーク透過的}である(例外はある)。 |
$B$i$+$K$5$l$F$$$J$$$,!"(B{\bf $BBgItJ,$O%M%C%H%o!<%/F)2aE*(B}$B$G$"$k(B($BNc30$O$"$k(B)$B!#(B |
|
|
まず、MathLink の通信路で交換されるデータが何なのか、ということを理解す |
$B$^$:!"(BMathLink $B$NDL?.O)$G8r49$5$l$k%G!<%?$,2?$J$N$+!"$H$$$&$3$H$rM}2r$9(B |
る必要がある。答は{\bf Mathematicaの式}である。これは自明ではない。 |
$B$kI,MW$,$"$k!#Ez$O(B{\bf Mathematica$B$N<0(B}$B$G$"$k!#$3$l$O<+L@$G$O$J$$!#(B |
次のような式がその例である。 |
$B<!$N$h$&$J<0$,$=$NNc$G$"$k!#(B |
\begin{verbatim} |
\begin{verbatim} |
EvaluatePacket[Sin[\$VersionNumber]] |
EvaluatePacket[Sin[\$VersionNumber]] |
ReturnPacket[Sin[x]] |
ReturnPacket[Sin[x]] |
InputNamePacket["In[1]:= "] |
InputNamePacket["In[1]:= "] |
MenuPacket[1,"Interrupt> "] |
MenuPacket[1,"Interrupt> "] |
\end{verbatim} |
\end{verbatim} |
このような *Packet[] を \cite{Wolfram-1996}ではパケットと呼んでいる. |
$B$3$N$h$&$J(B *Packet[] $B$r(B \cite{Wolfram-1996}$B$G$O%Q%1%C%H$H8F$s$G$$$k(B. |
MathLink を用いて、確実なプログラミングをするためには、これらのパケット |
MathLink $B$rMQ$$$F!"3N<B$J%W%m%0%i%_%s%0$r$9$k$?$a$K$O!"$3$l$i$N%Q%1%C%H(B |
を正しく扱う必要がある。 |
$B$r@5$7$/07$&I,MW$,$"$k!#(B |
|
|
さて、Mathematica Kernel の起動および通信路の確立については省略する。 |
$B$5$F!"(BMathematica Kernel $B$N5/F0$*$h$SDL?.O)$N3NN)$K$D$$$F$O>JN,$9$k!#(B |
いったん、通信路が確立されたら、 |
$B$$$C$?$s!"DL?.O)$,3NN)$5$l$?$i!"(B |
\begin{enumerate} |
\begin{enumerate} |
\item Mathematica Kernel に式を送る。 |
\item Mathematica Kernel $B$K<0$rAw$k!#(B |
\item Mathematica Kernel から式を受け取る。 |
\item Mathematica Kernel $B$+$i<0$r<u$1<h$k!#(B |
\end{enumerate} |
\end{enumerate} |
を繰り返すのが MathLink でのプログラミングである。 |
$B$r7+$jJV$9$N$,(B MathLink $B$G$N%W%m%0%i%_%s%0$G$"$k!#(B |
|
|
\oxmath は Mathematica と以下のような意味で{\bf 文字列ベース}で通信して |
\oxmath $B$O(B Mathematica $B$H0J2<$N$h$&$J0UL#$G(B{\bf $BJ8;zNs%Y!<%9(B}$B$GDL?.$7$F(B |
いる。まず Mathematica Kernel に評価させたい式が、C 言語の文字列で与えら |
$B$$$k!#$^$:(B Mathematica Kernel $B$KI>2A$5$;$?$$<0$,!"(BC $B8@8l$NJ8;zNs$GM?$($i(B |
れているとして、link で指し示すMathematica Kernel に |
$B$l$F$$$k$H$7$F!"(Blink $B$G;X$7<($9(BMathematica Kernel $B$K(B |
\begin{verbatim} |
\begin{verbatim} |
int ml_evaluateStringByLocalParser(char *string) |
int ml_evaluateStringByLocalParser(char *string) |
{ |
{ |
Line 107 int ml_evaluateStringByLocalParser(char *string) |
|
Line 107 int ml_evaluateStringByLocalParser(char *string) |
|
MLEndPacket(link); |
MLEndPacket(link); |
} |
} |
\end{verbatim} |
\end{verbatim} |
として送信する。パケットは、 |
$B$H$7$FAw?.$9$k!#%Q%1%C%H$O!"(B |
EvaluatePacket[ToExpression[{\it string}]] である。 |
EvaluatePacket[ToExpression[{\it string}]] $B$G$"$k!#(B |
ここで ToExpression は Mathematica の組み込み関数であり, |
$B$3$3$G(B ToExpression $B$O(B Mathematica $B$NAH$_9~$_4X?t$G$"$j(B, |
文字列 {\it string} を引数として Mathematica の式を返す. |
$BJ8;zNs(B {\it string} $B$r0z?t$H$7$F(B Mathematica $B$N<0$rJV$9(B. |
(\cite[pp.407]{Wolfram-1996}) |
(\cite[pp.407]{Wolfram-1996}) |
|
|
評価された結果を配列 str に格納するには、単純には次のようになる。 |
$BI>2A$5$l$?7k2L$rG[Ns(B str $B$K3JG<$9$k$K$O!"C1=c$K$O<!$N$h$&$K$J$k!#(B |
\begin{verbatim} |
\begin{verbatim} |
int receive_sample(char str[]) |
int receive_sample(char str[]) |
{ |
{ |
Line 129 int receive_sample(char str[]) |
|
Line 129 int receive_sample(char str[]) |
|
MLNewPacket(link); |
MLNewPacket(link); |
} |
} |
\end{verbatim} |
\end{verbatim} |
この例では ReturnPacket[] 以外を無視しているが、実際にはこんなに単純には |
$B$3$NNc$G$O(B ReturnPacket[] $B0J30$rL5;k$7$F$$$k$,!"<B:]$K$O$3$s$J$KC1=c$K$O(B |
書けない。\oxmath の実装では、mlo.c の |
$B=q$1$J$$!#(B\oxmath $B$N<BAu$G$O!"(Bmlo.c $B$N(B |
ml\_next\_packet(), ml\_new\_packet(), ml\_read\_packet(), |
ml\_next\_packet(), ml\_new\_packet(), ml\_read\_packet(), |
ml\_read\_returnpacket(), ml\_read\_menupacket(), ml\_read\_textpacket() |
ml\_read\_returnpacket(), ml\_read\_menupacket(), ml\_read\_textpacket() |
などを見てほしい。 |
$B$J$I$r8+$F$[$7$$!#(B |
|
|
\bigskip |
\bigskip |
|
|
文字列によらず、CMO を送ることもできる. |
$BJ8;zNs$K$h$i$:!"(BCMO $B$rAw$k$3$H$b$G$-$k(B. |
|
|
\oxmath は, CMO を次の規則で MathLink のオブジェクトに変換する. |
\oxmath $B$O(B, CMO $B$r<!$N5,B'$G(B MathLink $B$N%*%V%8%'%/%H$KJQ49$9$k(B. |
\[ |
\[ |
\begin{array}{lcl} |
\begin{array}{lcl} |
\mbox {CMO\_INT32} & \to & \mbox{MLTKINT}, \\ |
\mbox {CMO\_INT32} & \to & \mbox{MLTKINT}, \\ |
\mbox {CMO\_STRING} & \to & \mbox{MLTKSTR}, \\ |
\mbox {CMO\_STRING} & \to & \mbox{MLTKSTR}, \\ |
\mbox {CMO\_LIST} & \to & \mbox{MLTKFUNC}, \\ |
\mbox {CMO\_LIST} & \to & \mbox{MLTKFUNC}, \\ |
\mbox {その他の CMO} & \to & \mbox{ToExpression[文字列]} |
\mbox {$B$=$NB>$N(B CMO} & \to & \mbox{ToExpression[$BJ8;zNs(B]} |
\end{array} |
\end{array} |
\] |
\] |
逆に MathLink のオブジェクトは次の規則で CMO に変換される. |
$B5U$K(B MathLink $B$N%*%V%8%'%/%H$O<!$N5,B'$G(B CMO $B$KJQ49$5$l$k(B. |
\[ |
\[ |
\begin{array}{lcl} |
\begin{array}{lcl} |
\mbox {MLTKERR} & \to & \mbox{CMO\_ERROR2}, \\ |
\mbox {MLTKERR} & \to & \mbox{CMO\_ERROR2}, \\ |
Line 159 ml\_read\_returnpacket(), ml\_read\_menupacket(), ml\_ |
|
Line 159 ml\_read\_returnpacket(), ml\_read\_menupacket(), ml\_ |
|
\mbox {MLTKFUNC} & \to & \mbox{CMO\_LIST} |
\mbox {MLTKFUNC} & \to & \mbox{CMO\_LIST} |
\end{array} |
\end{array} |
\] |
\] |
この変換規則は明らかに可逆でないので注意. |
$B$3$NJQ495,B'$OL@$i$+$K2D5U$G$J$$$N$GCm0U(B. |
|
|
\bigskip |
\bigskip |
|
|
CMO\_ZZ をもとに実装を説明しよう. |
CMO\_ZZ $B$r$b$H$K<BAu$r@bL@$7$h$&(B. |
まず, MLTKINT は多倍長整数型であるが, MathLink の内部データ構造が |
$B$^$:(B, MLTKINT $B$OB?G\D9@0?t7?$G$"$k$,(B, MathLink $B$NFbIt%G!<%?9=B$$,(B |
公開されていないため, |
$B8x3+$5$l$F$$$J$$$?$a(B, |
CMO\_ZZ (あるいは GNU GMP library の整数)を直接 MLTKINT に |
CMO\_ZZ ($B$"$k$$$O(B GNU GMP library $B$N@0?t(B)$B$rD>@\(B MLTKINT $B$K(B |
変換することはできない. つまり CMO\_ZZ が整数型であると MathLink に知ら |
$BJQ49$9$k$3$H$O$G$-$J$$(B. $B$D$^$j(B CMO\_ZZ $B$,@0?t7?$G$"$k$H(B MathLink $B$KCN$i(B |
せることはできない. そこで, 次のような方法をとることになる. |
$B$;$k$3$H$O$G$-$J$$(B. $B$=$3$G(B, $B<!$N$h$&$JJ}K!$r$H$k$3$H$K$J$k(B. |
|
|
\begin{verbatim} |
\begin{verbatim} |
export MLINK link; |
export MLINK link; |
Line 179 int ml_send_cmo_zz(cmo *m) |
|
Line 179 int ml_send_cmo_zz(cmo *m) |
|
} |
} |
\end{verbatim} |
\end{verbatim} |
|
|
このようにすると, Mathematica 側では, 例えば ToExpression["1234567890"] |
$B$3$N$h$&$K$9$k$H(B, Mathematica $BB&$G$O(B, $BNc$($P(B ToExpression["1234567890"] |
の評価が行われ, 文字列データから整数 1234567890 が復元される. |
$B$NI>2A$,9T$o$l(B, $BJ8;zNs%G!<%?$+$i@0?t(B 1234567890 $B$,I|85$5$l$k(B. |
|
|
逆に, Mathematica から送られた多倍長整数は, マシン整数の範囲内であれば, |
$B5U$K(B, Mathematica $B$+$iAw$i$l$?B?G\D9@0?t$O(B, $B%^%7%s@0?t$NHO0OFb$G$"$l$P(B, |
int として取得可能(MLGetInteger を使う)であるが, 受け取る前に int に収ま |
int $B$H$7$F<hF@2DG=(B(MLGetInteger $B$r;H$&(B)$B$G$"$k$,(B, $B<u$1<h$kA0$K(B int $B$K<}$^(B |
るか否かを知ることはできない. int に収まらない場合、データが切り捨てられ |
$B$k$+H]$+$rCN$k$3$H$O$G$-$J$$(B. int $B$K<}$^$i$J$$>l9g!"%G!<%?$,@Z$j<N$F$i$l(B |
てしまうので注意が必要である. また, 直接 CMO\_ZZ として取得することも不 |
$B$F$7$^$&$N$GCm0U$,I,MW$G$"$k(B. $B$^$?(B, $BD>@\(B CMO\_ZZ $B$H$7$F<hF@$9$k$3$H$bIT(B |
可能である. (MathLink 上でどのような形式でデータ交換されているのかの情 |
$B2DG=$G$"$k(B. (MathLink $B>e$G$I$N$h$&$J7A<0$G%G!<%?8r49$5$l$F$$$k$N$+$N>p(B |
報は手元にある資料からは得られなかった) |
$BJs$O<j85$K$"$k;qNA$+$i$OF@$i$l$J$+$C$?(B) |
|
|
しかしながら, たとえ Mathematica 側から整数データが送られていたとしても, |
$B$7$+$7$J$,$i(B, $B$?$H$((B Mathematica $BB&$+$i@0?t%G!<%?$,Aw$i$l$F$$$?$H$7$F$b(B, |
そのデータを文字列に変換して受け取ることは MathLink の機構上可能である. |
$B$=$N%G!<%?$rJ8;zNs$KJQ49$7$F<u$1<h$k$3$H$O(B MathLink $B$N5!9=>e2DG=$G$"$k(B. |
|
|
これを利用して, 我々は次のようにして整数を受け取る. |
$B$3$l$rMxMQ$7$F(B, $B2f!9$O<!$N$h$&$K$7$F@0?t$r<u$1<h$k(B. |
\begin{verbatim} |
\begin{verbatim} |
export MLINK link; |
export MLINK link; |
cmo_zz* ml_receive_cmo_zz() |
cmo_zz* ml_receive_cmo_zz() |
Line 208 cmo_zz* ml_receive_cmo_zz() |
|
Line 208 cmo_zz* ml_receive_cmo_zz() |
|
} |
} |
\end{verbatim} |
\end{verbatim} |
|
|
つまり、Mathematica から整数を文字列として受け取り、その文字列を |
$B$D$^$j!"(BMathematica $B$+$i@0?t$rJ8;zNs$H$7$F<u$1<h$j!"$=$NJ8;zNs$r(B |
\oxmath が CMO\_ZZ に直している。 |
\oxmath $B$,(B CMO\_ZZ $B$KD>$7$F$$$k!#(B |
|
|
% このように基本的に MathLink では全てのデータを文字列で受け取るしか方法は |
% $B$3$N$h$&$K4pK\E*$K(B MathLink $B$G$OA4$F$N%G!<%?$rJ8;zNs$G<u$1<h$k$7$+J}K!$O(B |
% ない。どのような種類のデータであるかは受け取る前に知ることはできる。デー |
% $B$J$$!#$I$N$h$&$J<oN`$N%G!<%?$G$"$k$+$O<u$1<h$kA0$KCN$k$3$H$O$G$-$k!#%G!<(B |
% タの型は、MLTKERR(エラー), MLTKINT(整数), MLTKSTR(文字列), MLTKREAL(実数), |
% $B%?$N7?$O!"(BMLTKERR($B%(%i!<(B), MLTKINT($B@0?t(B), MLTKSTR($BJ8;zNs(B), MLTKREAL($B<B?t(B), |
% MLTKSYM (シンボル), MLTKFUNC(関数) のいずれかである。このような事情で |
% MLTKSYM ($B%7%s%\%k(B), MLTKFUNC($B4X?t(B) $B$N$$$:$l$+$G$"$k!#$3$N$h$&$J;v>p$G(B |
% Mathematica から受け取ったデータは基本的に CMO\_STRINGとしてスタックに積 |
% Mathematica $B$+$i<u$1<h$C$?%G!<%?$O4pK\E*$K(B CMO\_STRING$B$H$7$F%9%?%C%/$K@Q(B |
% まれるので、クライアント側でその文字列の解釈をする必要がでてくる。しかし |
% $B$^$l$k$N$G!"%/%i%$%"%s%HB&$G$=$NJ8;zNs$N2r<a$r$9$kI,MW$,$G$F$/$k!#$7$+$7(B |
% ながら、全ての MathLink オブジェクトが文字列に変換できるわけではないので、 |
% $B$J$,$i!"A4$F$N(B MathLink $B%*%V%8%'%/%H$,J8;zNs$KJQ49$G$-$k$o$1$G$O$J$$$N$G!"(B |
% その取り扱いには注意を要する。 |
% $B$=$N<h$j07$$$K$OCm0U$rMW$9$k!#(B |
|
|
\section{\oxmath への計算中断機能の実装} |
\section{\oxmath $B$X$N7W;;CfCG5!G=$N<BAu(B} |
|
|
\noindent |
\noindent |
{\bf 注意: {\tt ox\_math\_interruption.tex} |
{\bf $BCm0U(B: {\tt ox\_math\_interruption.tex} |
に Risa/Asir Conference (2003) での講演原稿がある.} |
$B$K(B Risa/Asir Conference (2003) $B$G$N9V1i869F$,$"$k(B.} |
|
|
OpenXM プロトコルは、エンジンに対して、計算中断機能を要求する。\oxmath |
OpenXM $B%W%m%H%3%k$O!"%(%s%8%s$KBP$7$F!"7W;;CfCG5!G=$rMW5a$9$k!#(B\oxmath |
のような wrapper プログラムでは、そのような機能を実装するのは一般には難 |
$B$N$h$&$J(B wrapper $B%W%m%0%i%`$G$O!"$=$N$h$&$J5!G=$r<BAu$9$k$N$O0lHL$K$OFq(B |
しいが、MathLink には Mathematica Book~\cite{Wolfram-1996} に書かれてい |
$B$7$$$,!"(BMathLink $B$K$O(B Mathematica Book~\cite{Wolfram-1996} $B$K=q$+$l$F$$(B |
ない機能があり(\cite{MathSource-Google1}, \cite{MathSource-Google2}, |
$B$J$$5!G=$,$"$j(B(\cite{MathSource-Google1}, \cite{MathSource-Google2}, |
\cite{Math-Output1})、そのひとつを用いて、\oxmath に計算中断機能を実装し |
\cite{Math-Output1})$B!"$=$N$R$H$D$rMQ$$$F!"(B\oxmath $B$K7W;;CfCG5!G=$r<BAu$7(B |
た。この節では、その実装について説明する。 |
$B$?!#$3$N@a$G$O!"$=$N<BAu$K$D$$$F@bL@$9$k!#(B |
|
|
Mathematica Kernel に対する割り込みは、 |
Mathematica Kernel $B$KBP$9$k3d$j9~$_$O!"(B |
\begin{enumerate} |
\begin{enumerate} |
\item MLPutMessage で Mathematica Kernel に MLInterruptMessage を送る。 |
\item MLPutMessage $B$G(B Mathematica Kernel $B$K(B MLInterruptMessage $B$rAw$k!#(B |
\item 通信路の後始末を行い、最終的に ReturnPacket[\$Aborted] を受け取る。 |
\item $BDL?.O)$N8e;OKv$r9T$$!":G=*E*$K(B ReturnPacket[\$Aborted] $B$r<u$1<h$k!#(B |
\end{enumerate} |
\end{enumerate} |
ことでなされる。 |
$B$3$H$G$J$5$l$k!#(B |
MLPutMessage は MathLink の非公開関数でネットワーク透過性はない。 |
MLPutMessage $B$O(B MathLink $B$NHs8x3+4X?t$G%M%C%H%o!<%/F)2a@-$O$J$$!#(B |
Unix と Windows では異なるが、Unix の場合、MLInterruptMessage の実体は |
Unix $B$H(B Windows $B$G$O0[$J$k$,!"(BUnix $B$N>l9g!"(BMLInterruptMessage $B$N<BBN$O(B |
SIGINT である。 |
SIGINT $B$G$"$k!#(B |
通信路の後始末には、{\bf Mathematica Kernel のバージョン依存性がある}ので、 |
$BDL?.O)$N8e;OKv$K$O!"(B{\bf Mathematica Kernel $B$N%P!<%8%g%s0MB8@-$,$"$k(B}$B$N$G!"(B |
それを回避すると、結局、次の手順になる。 |
$B$=$l$r2sHr$9$k$H!"7k6I!"<!$N<j=g$K$J$k!#(B |
\begin{enumerate} |
\begin{enumerate} |
\item MLPutMessage(link, MLInterruptMessage) |
\item MLPutMessage(link, MLInterruptMessage) |
\item MenuPacket[1,"Interrupt> "] を受け取れば計算が中断されている |
\item MenuPacket[1,"Interrupt> "] $B$r<u$1<h$l$P7W;;$,CfCG$5$l$F$$$k(B |
\item MLPutString(link, "$\backslash$n") |
\item MLPutString(link, "$\backslash$n") |
\item MenuPacket[0,"Interrupt> "] を受け取る |
\item MenuPacket[0,"Interrupt> "] $B$r<u$1<h$k(B |
\item MLPutString(link, "a") |
\item MLPutString(link, "a") |
\item TextPacket["..."] を受け取る |
\item TextPacket["..."] $B$r<u$1<h$k(B |
\item EvaluatePacket[0] を送って、ReturnPacket[...] をふたつ受け取る。 |
\item EvaluatePacket[0] $B$rAw$C$F!"(BReturnPacket[...] $B$r$U$?$D<u$1<h$k!#(B |
最初のものが ReturnPacket[\$Aborted] である。 |
$B:G=i$N$b$N$,(B ReturnPacket[\$Aborted] $B$G$"$k!#(B |
\end{enumerate} |
\end{enumerate} |
|
|
最後の手順を説明する。 |
$B:G8e$N<j=g$r@bL@$9$k!#(B |
ここで、ReturnPacket[\$Aborted] が素直に返ってくればいいのであるが、 |
$B$3$3$G!"(BReturnPacket[\$Aborted] $B$,AGD>$KJV$C$F$/$l$P$$$$$N$G$"$k$,!"(B |
バージョン 3.x では返ってくるのに、バージョン4.xでは、何故か、 |
$B%P!<%8%g%s(B 3.x $B$G$OJV$C$F$/$k$N$K!"%P!<%8%g%s(B4.x$B$G$O!"2?8N$+!"(B |
返ってこず、次の計算を行うとき、ふたつまとめて返ってくる。 |
$BJV$C$F$3$:!"<!$N7W;;$r9T$&$H$-!"$U$?$D$^$H$a$FJV$C$F$/$k!#(B |
よって、ダミーにEvaluatePacket[0] を送るのである。 |
$B$h$C$F!"%@%_!<$K(BEvaluatePacket[0] $B$rAw$k$N$G$"$k!#(B |
|
|
\section{Mathematica を OX のクライアントに} |
\section{Mathematica $B$r(B OX $B$N%/%i%$%"%s%H$K(B} |
|
|
OpenXM クライアントは Mathematica の外部プログラム({\tt math2ox}) の形で |
OpenXM $B%/%i%$%"%s%H$O(B Mathematica $B$N30It%W%m%0%i%`(B({\tt math2ox}) $B$N7A$G(B |
実現されている。すなわち、Mathematica と math2ox の間は MathLink プロト |
$B<B8=$5$l$F$$$k!#$9$J$o$A!"(BMathematica $B$H(B math2ox $B$N4V$O(B MathLink $B%W%m%H(B |
コルで、math2ox と OpenXM サーバの間は OpenXM プロトコルで通信し、 |
$B%3%k$G!"(Bmath2ox $B$H(B OpenXM $B%5!<%P$N4V$O(B OpenXM $B%W%m%H%3%k$GDL?.$7!"(B |
math2ox が適切に情報を変換しながらやりとりする。その意味で wrapper の一 |
math2ox $B$,E,@Z$K>pJs$rJQ49$7$J$,$i$d$j$H$j$9$k!#$=$N0UL#$G(B wrapper $B$N0l(B |
種であるとも言える。 |
$B<o$G$"$k$H$b8@$($k!#(B |
|
|
利用するには、最初に |
$BMxMQ$9$k$K$O!":G=i$K(B |
\begin{verbatim} |
\begin{verbatim} |
In[1]:= Install["math2ox"] |
In[1]:= Install["math2ox"] |
\end{verbatim} |
\end{verbatim} |
として、math2ox をロードしなければならない。 |
$B$H$7$F!"(Bmath2ox $B$r%m!<%I$7$J$1$l$P$J$i$J$$!#(B |
Mathematica に新たに定義されるコマンドは、\\ |
Mathematica $B$K?7$?$KDj5A$5$l$k%3%^%s%I$O!"(B\\ |
{\tt OxStart[s\_String], OxStartInsecure[s\_String, p\_Integer, q\_Integer], |
{\tt OxStart[s\_String], OxStartInsecure[s\_String, p\_Integer, q\_Integer], |
\\ |
\\ |
OxStartRemoteSSH[s\_String, host\_String], |
OxStartRemoteSSH[s\_String, host\_String], |
Line 291 OxPopString[id\_Integer], |
|
Line 291 OxPopString[id\_Integer], |
|
OxClose[id\_Integer], |
OxClose[id\_Integer], |
OxReset[id\_Integer]} |
OxReset[id\_Integer]} |
\\ |
\\ |
の11個である。 |
$B$N(B11$B8D$G$"$k!#(B |
|
|
math2ox をロードしたら、 |
math2ox $B$r%m!<%I$7$?$i!"(B |
\begin{verbatim} |
\begin{verbatim} |
In[2] := pid = OxStart["ox_sm1"] |
In[2] := pid = OxStart["ox_sm1"] |
\end{verbatim} |
\end{verbatim} |
によって OpenXM サーバに接続する。この場合の接続先は ox\_sm1 である。 |
$B$K$h$C$F(B OpenXM $B%5!<%P$K@\B3$9$k!#$3$N>l9g$N@\B3@h$O(B ox\_sm1 $B$G$"$k!#(B |
返り値 pid は、セッション番号である。 |
$BJV$jCM(B pid $B$O!"%;%C%7%g%sHV9f$G$"$k!#(B |
もちろん |
$B$b$A$m$s(B |
\begin{verbatim} |
\begin{verbatim} |
In[2] := pid = OxStartInsecure["water.s.kanazawa-u.ac.jp", 1300, 1400] |
In[2] := pid = OxStartInsecure["water.s.kanazawa-u.ac.jp", 1300, 1400] |
\end{verbatim} |
\end{verbatim} |
のようにして、insecure モードで接続してもよい。ただしこの場合は、 |
$B$N$h$&$K$7$F!"(Binsecure $B%b!<%I$G@\B3$7$F$b$h$$!#$?$@$7$3$N>l9g$O!"(B |
あらかじめ {\tt Run[]} 等で、OpenXM サーバを起動しておかなければならない。 |
$B$"$i$+$8$a(B {\tt Run[]} $BEy$G!"(BOpenXM $B%5!<%P$r5/F0$7$F$*$+$J$1$l$P$J$i$J$$!#(B |
|
|
接続が成功したらデータを送ってみよう。 |
$B@\B3$,@.8y$7$?$i%G!<%?$rAw$C$F$_$h$&!#(B |
\begin{verbatim} |
\begin{verbatim} |
In[3] := OxParse[pid, "(CMO_LIST, (CMO_STRING, "hello world"), (CMO_ZERO))"] |
In[3] := OxParse[pid, "(CMO_LIST, (CMO_STRING, "hello world"), (CMO_ZERO))"] |
\end{verbatim} |
\end{verbatim} |
のように CMO expression を指定することによって、 |
$B$N$h$&$K(B CMO expression $B$r;XDj$9$k$3$H$K$h$C$F!"(B |
任意の CMO を送信できる。 |
$BG$0U$N(B CMO $B$rAw?.$G$-$k!#(B |
正しくない CMO の場合には、何も送信されない。 |
$B@5$7$/$J$$(B CMO $B$N>l9g$K$O!"2?$bAw?.$5$l$J$$!#(B |
また、CMO ではなく、 |
$B$^$?!"(BCMO $B$G$O$J$/!"(B |
\begin{verbatim} |
\begin{verbatim} |
In[4] := OxParse[pid, "(OX_COMMAND, (SM_popCMO))"] |
In[4] := OxParse[pid, "(OX_COMMAND, (SM_popCMO))"] |
\end{verbatim} |
\end{verbatim} |
などとして、OX メッセージの形で記述することもできる。 |
$B$J$I$H$7$F!"(BOX $B%a%C%;!<%8$N7A$G5-=R$9$k$3$H$b$G$-$k!#(B |
注意しなければならないのは、SM コマンドの場合、OX スタックマシンから |
$BCm0U$7$J$1$l$P$J$i$J$$$N$O!"(BSM $B%3%^%s%I$N>l9g!"(BOX $B%9%?%C%/%^%7%s$+$i(B |
OX メッセージが送られてくる場合があるが、OxParse[] を用いた場合、 |
OX $B%a%C%;!<%8$,Aw$i$l$F$/$k>l9g$,$"$k$,!"(BOxParse[] $B$rMQ$$$?>l9g!"(B |
このメッセージは自動的には受信しない(現在の仕様では)。したがって明示的に |
$B$3$N%a%C%;!<%8$O<+F0E*$K$O<u?.$7$J$$(B($B8=:_$N;EMM$G$O(B)$B!#$7$?$,$C$FL@<(E*$K(B |
受信する必要がある。そのためには |
$B<u?.$9$kI,MW$,$"$k!#$=$N$?$a$K$O(B |
\begin{verbatim} |
\begin{verbatim} |
In[5] := OxGet[pid] |
In[5] := OxGet[pid] |
\end{verbatim} |
\end{verbatim} |
とするだけでよい。返ってくるオブジェクトは CMO に対応するものである。 |
$B$H$9$k$@$1$G$h$$!#JV$C$F$/$k%*%V%8%'%/%H$O(B CMO $B$KBP1~$9$k$b$N$G$"$k!#(B |
\begin{verbatim} |
\begin{verbatim} |
In[6] := OxPopCMO[pid] |
In[6] := OxPopCMO[pid] |
\end{verbatim} |
\end{verbatim} |
を用いる場合にはもちろん {\tt OxGet[pid]} を呼び出す必要はない。 |
$B$rMQ$$$k>l9g$K$O$b$A$m$s(B {\tt OxGet[pid]} $B$r8F$S=P$9I,MW$O$J$$!#(B |
|
|
計算を実行するには {\tt OxExecute[pid, ...]} |
$B7W;;$r<B9T$9$k$K$O(B {\tt OxExecute[pid, ...]} |
(SM\_executeStringByLocalParser) か、適切な OX メッセージを送信すること。 |
(SM\_executeStringByLocalParser) $B$+!"E,@Z$J(B OX $B%a%C%;!<%8$rAw?.$9$k$3$H!#(B |
|
|
計算が終わったら、 |
$B7W;;$,=*$o$C$?$i!"(B |
\begin{verbatim} |
\begin{verbatim} |
In[7] := OxClose[pid] |
In[7] := OxClose[pid] |
\end{verbatim} |
\end{verbatim} |
とすると、接続が終了する。 |
$B$H$9$k$H!"@\B3$,=*N;$9$k!#(B |
|
|
\appendix |
\appendix |
\section{付録} |
\section{$BIUO?(B} |
|
|
GMP における ``整数型'' {\tt mpz\_t} はつぎのような |
GMP $B$K$*$1$k(B ``$B@0?t7?(B'' {\tt mpz\_t} $B$O$D$.$N$h$&$J(B |
内部表現を持つ: \\ |
$BFbItI=8=$r;}$D(B: \\ |
まず {\tt mpz\_t} 型は |
$B$^$:(B {\tt mpz\_t} $B7?$O(B |
\begin{verbatim} |
\begin{verbatim} |
typedef struct __mpz_struct mpz_t[1]; |
typedef struct __mpz_struct mpz_t[1]; |
\end{verbatim} |
\end{verbatim} |
と typedef されており, |
$B$H(B typedef $B$5$l$F$*$j(B, |
{\tt mpz\_t} 型の変数は(関数の仮引数でない限り)配列の |
{\tt mpz\_t} $B7?$NJQ?t$O(B($B4X?t$N2>0z?t$G$J$$8B$j(B)$BG[Ns$N(B |
扱いである. また, |
$B07$$$G$"$k(B. $B$^$?(B, |
\begin{verbatim} |
\begin{verbatim} |
typedef unsigned long int mp_limb_t; |
typedef unsigned long int mp_limb_t; |
\end{verbatim} |
\end{verbatim} |
と宣言されている場合には, |
$B$H@k8@$5$l$F$$$k>l9g$K$O(B, |
変数 {\tt mpz\_t x} の {\tt x->\_mp\_d} が unsigned long int の |
$BJQ?t(B {\tt mpz\_t x} $B$N(B {\tt x->\_mp\_d} $B$,(B unsigned long int $B$N(B |
配列であり, データの実体である. |
$BG[Ns$G$"$j(B, $B%G!<%?$N<BBN$G$"$k(B. |
これは整数の最下位4バイトが配列の先頭にくる. |
$B$3$l$O@0?t$N:G2<0L(B4$B%P%$%H$,G[Ns$N@hF,$K$/$k(B. |
つまり全体としては``リトルエンディアンっぽい''が, |
$B$D$^$jA4BN$H$7$F$O(B``$B%j%H%k%(%s%G%#%"%s$C$]$$(B''$B$,(B, |
各 unsigned long int はマシンのネイティブな integer である. |
$B3F(B unsigned long int $B$O%^%7%s$N%M%$%F%#%V$J(B integer $B$G$"$k(B. |
つまり, GMP の内部表現はマシン依存となっている. |
$B$D$^$j(B, GMP $B$NFbItI=8=$O%^%7%s0MB8$H$J$C$F$$$k(B. |
|
|
\begin{thebibliography}{99} |
\begin{thebibliography}{99} |
\bibitem{Openxxx-1998} |
\bibitem{Openxxx-1998} |
野呂正行, 高山信毅. |
$BLnO$@59T(B, $B9b;3?.5#(B. |
{Open XM の設計と実装 --- Open message eXchange protocol for Mathematics}, |
{Open XM $B$N@_7W$H<BAu(B --- Open message eXchange protocol for Mathematics}, |
November 22, 1999, Revised March 4, 2005. |
November 22, 1999, Revised March 4, 2005. |
\bibitem{Ohara-Takayama-Noro-1999} |
\bibitem{Ohara-Takayama-Noro-1999} |
小原功任, 高山信毅, 野呂正行. |
$B>.868yG$(B, $B9b;3?.5#(B, $BLnO$@59T(B. |
{Open asir 入門}, 1999, 数式処理, Vol 7, No 2, 2--17. (ISBN4-87243-086-7, SEG 出版, Tokyo). |
{Open asir $BF~Lg(B}, 1999, $B?t<0=hM}(B, Vol 7, No 2, 2--17. (ISBN4-87243-086-7, SEG $B=PHG(B, Tokyo). |
\bibitem{Wolfram-1992} |
\bibitem{Wolfram-1992} |
ウルフラム. |
$B%&%k%U%i%`(B. |
{Mathematica (日本語版)}, |
{Mathematica ($BF|K\8lHG(B)}, |
アジソンウエスレイ, 1992. |
$B%"%8%=%s%&%(%9%l%$(B, 1992. |
\bibitem{Wolfram-1996} |
\bibitem{Wolfram-1996} |
Stephen Wolfram. |
Stephen Wolfram. |
{The Mathematica Book}, Third edition, |
{The Mathematica Book}, Third edition, |
Wolfram Media/Cambridge University Press, 1996. |
Wolfram Media/Cambridge University Press, 1996. |
\bibitem{miyachi-1998} |
\bibitem{miyachi-1998} |
宮地力. |
$B5\CONO(B. |
{Mathematica によるネットワークプログラミング}, |
{Mathematica $B$K$h$k%M%C%H%o!<%/%W%m%0%i%_%s%0(B}, |
岩波コンピュータサイエンス, |
$B4dGH%3%s%T%e!<%?%5%$%(%s%9(B, |
岩波書店, 1998. |
$B4dGH=qE9(B, 1998. |
\bibitem{MathSource-Google1} |
\bibitem{MathSource-Google1} |
Todd Gayley. |
Todd Gayley. |
[mg17015] in MathArchive, |
[mg17015] in MathArchive, |
1999 April. |
1999 April. |
\bibitem{MathSource-Google2} |
\bibitem{MathSource-Google2} |
昔の MathLink にあった MLSignal の解説. |
$B@N$N(B MathLink $B$K$"$C$?(B MLSignal $B$N2r@b(B. |
(以前、Google のキャッシュにあったが、もうない) |
($B0JA0!"(BGoogle $B$N%-%c%C%7%e$K$"$C$?$,!"$b$&$J$$(B) |
\bibitem{Math-Output1} |
\bibitem{Math-Output1} |
mathlink.h, libMLa のシンボル表, mprep の生成するソース. |
mathlink.h, libMLa $B$N%7%s%\%kI=(B, mprep $B$N@8@.$9$k%=!<%9(B. |
\end{thebibliography} |
\end{thebibliography} |
|
|
\end{document} |
\end{document} |