[BACK]Return to ox_math.tex CVS log [TXT][DIR] Up to [local] / OpenXM / src / ox_math / documents

Annotation of OpenXM/src/ox_math/documents/ox_math.tex, Revision 1.8

1.1       ohara       1: %#!platex
1.8     ! ohara       2: %% $OpenXM: OpenXM/src/ox_math/documents/ox_math.tex,v 1.7 2002/04/17 01:09:23 takayama Exp $
1.1       ohara       3:
                      4: \documentclass{jarticle}
                      5: \title{Mathematica の Open XM 化について
                      6: % \\ {\small --- Open Mathematica サーバの内部構成 ---}
                      7: }
                      8: %\date{January 19, 1999}
1.4       ohara       9: %\date{July 12, 1999}
1.8     ! ohara      10: \date{November 25, 1999\\
        !            11: (Revised July 20, 2005)
        !            12: }
1.1       ohara      13: \author{小原功任}
                     14:
1.8     ! ohara      15: \def\oxmath{{\tt ox\_math}}
        !            16:
1.1       ohara      17: \begin{document}
                     18: \maketitle
1.7       takayama   19:
                     20: \noindent
                     21: {\bf
                     22: 注意 (2002.04.17):
                     23: この文書は, 古いインタフェースをもとに記述してあるので,
                     24: 例はこのままでは動作しないので注意.
                     25: math2ox.texi が最新のインタフェースのマニュアルである.
                     26: 一番の変更点は, {\tt OxStart} が pid (ox process id) を戻すようになり,
                     27: {\tt OxParse} など多くの関数が, pid を引数として求めるようになったことで
                     28: ある.
                     29: たとえば, この文書の {\tt OxParse} を用いる例は, 次のように変更しないと
                     30: いけない.}
                     31: \begin{verbatim}
                     32: Install["math2ox"]
                     33: pid = OxStart["ox_sm1"]
                     34: OxParse[pid,"(CMO_ZERO)"]
                     35: OxPopCMO[pid]
                     36: \end{verbatim}
                     37:
1.1       ohara      38:
1.6       ohara      39: \section{我々が提供するもの}
                     40:
                     41: 我々が提供するのは二つのプログラムとそのソースである。一つ目は
1.8     ! ohara      42: \oxmath プログラムであり、これは OpenXM サーバの一種である。二つ
1.6       ohara      43: 目は {\tt math2ox} であり、OpenXM クライアントである。
                     44:
1.8     ! ohara      45: 動作環境は Solaris, Linux および Windows、対象としている Mathematica の
        !            46: バージョンは、3.0 〜 4.2 までである。バージョン 5.x については、我々が所
        !            47: 有していないため調査していない。
        !            48:
        !            49: Windows 上では \oxmath は、cygwin のもとで動作する。\oxmath の Windows
        !            50: 対応は藤本さんによる(2002年4月)。ありがとう。
1.6       ohara      51:
                     52: \section{Open Mathematica サーバの構成}
1.1       ohara      53:
1.8     ! ohara      54: Open Mathmatica サーバ(\oxmath)はOpen XM クライアントおよび Mathematica
        !            55: Kernel と通信する。\oxmath は起動直後に Mathematica Kernel を起動し、
        !            56: Mathematica Kernel と協調して動作する。Mathematica Kernel とは MathLink
        !            57: ライブラリを利用して通信する。つまり \oxmath は MathLink
1.1       ohara      58: のラッパだと思ってよい。Open XM クライアントとの間はソケットを利用して通
1.8     ! ohara      59: 信する。\oxmath はファイルディスクリプタ 3,4 が既にオープ
1.1       ohara      60: ンされていると思って, 3 から読み込み、4 に書き出す。
                     61:
1.8     ! ohara      62: さらに \oxmath には計算中断機能が必要であるが、この機能は 2003年のはじめに実装された。
1.1       ohara      63:
                     64: \section{OX スタックマシン}
                     65: スタックのオブジェクトは cmo 型の変数、あるいはその派生クラスである.
                     66: つまり、Open XM 規約で定められたデータ形式を流用している.
                     67: % cmo 構造体およびその派生クラスは/home/ohara/openxxx/lib/oxlib.h で定義さ
                     68: % れている.
1.2       ohara      69: この方法の利点は Open XM プロトコルを通して通信するにあたって
1.1       ohara      70: 特にデータの変換を必要としないことである.  すなわちCMO の各データタイプ
                     71: は Open Mathematicaサーバ(スタックマシン)の内部でも, CMO として保持する
                     72: わけである.
                     73:
                     74: サーバの各関数は cmo* を受け取り、タグをみて実際のクラスが何であるかを
                     75: 知り、動作を決定する.
                     76:
1.8     ! ohara      77: \section{MathLink プログラミングの基礎知識}
        !            78:
        !            79: ここでは、MathLink についての基礎的事項を説明する。概ね、Mathematica
        !            80: Book~\cite{Wolfram-1996} や宮地~\cite{miyachi-1998} などを参照すればよい
        !            81: が、必ずしもこれらの書籍に明確に書かれているわけではない(探せば見つかる
        !            82: が)。
        !            83:
        !            84: まず MathLink とは、Wolfram が提供するライブラリであり、Mathematica のネッ
        !            85: トワーク対応部分に相当する。Mathematica Kernel と通信するプログラムを書
        !            86: こうとするならば、MathLink を利用する必要がある。MathLink の内部構成は明
        !            87: らかにされていないが、{\bf 大部分はネットワーク透過的}である(例外はある)。
        !            88:
        !            89: まず、MathLink の通信路で交換されるデータが何なのか、ということを理解す
        !            90: る必要がある。答は{\bf Mathematicaの式}である。これは自明ではない。
        !            91: 次のような式がその例である。
        !            92: \begin{verbatim}
        !            93:     EvaluatePacket[Sin[\$VersionNumber]]
        !            94:     ReturnPacket[Sin[x]]
        !            95:     InputNamePacket["In[1]:= "]
        !            96:     MenuPacket[1,"Interrupt> "]
        !            97: \end{verbatim}
        !            98: このような *Packet[] を \cite{Wolfram-1996}ではパケットと呼んでいる.
        !            99: MathLink を用いて、確実なプログラミングをするためには、これらのパケット
        !           100: を正しく扱う必要がある。
        !           101:
        !           102: さて、Mathematica Kernel の起動および通信路の確立については省略する。
        !           103: いったん、通信路が確立されたら、
        !           104: \begin{enumerate}
        !           105: \item Mathematica Kernel に式を送る。
        !           106: \item Mathematica Kernel から式を受け取る。
        !           107: \end{enumerate}
        !           108: を繰り返すのが MathLink でのプログラミングである。
        !           109:
        !           110: \oxmath は Mathematica と以下のような意味で{\bf 文字列ベース}で通信して
        !           111: いる。まず Mathematica Kernel に評価させたい式が、C 言語の文字列で与えら
        !           112: れているとして、link で指し示すMathematica Kernel に
        !           113: \begin{verbatim}
        !           114: int ml_evaluateStringByLocalParser(char *str)
        !           115: {
        !           116:     MLPutFunction(link, "EvaluatePacket", 1);
        !           117:     MLPutFunction(link, "ToExpression", 1);
        !           118:     MLPutString(link, str);
        !           119:     MLEndPacket(link);
        !           120: }
        !           121: \end{verbatim}
        !           122: として送信する。パケットは、
        !           123: EvaluatePacket[ToExpression[{\it str}]] である。
        !           124:
        !           125: 評価された結果を配列 str に格納するには、単純には次のようになる。
        !           126: \begin{verbatim}
        !           127: int receive_sample(char str[])
        !           128: {
        !           129:     while (MLNextPacket(link) != RETURNPKT)
        !           130:         MLNewPacket(link);
        !           131:     switch(MLGetNext(link)) {
        !           132:     MLTKSTR:
        !           133:         MLGetString(link, &str);
        !           134:         ...
        !           135:     MLTKINT:
        !           136:         ...
        !           137:     }
        !           138:     MLNewPacket(link);
        !           139: }
        !           140: \end{verbatim}
        !           141: この例では ReturnPacket[] 以外を無視しているが、実際にはこんなに単純には
        !           142: 書けない。\oxmath の実装では、mlo.c の
        !           143: ml\_next\_packet(), ml\_new\_packet(), ml\_read\_packet(),
        !           144: ml\_read\_returnpacket(), ml\_read\_menupacket(), ml\_read\_textpacket()
        !           145: などを見てほしい。
        !           146:
1.1       ohara     147: \section{Mathematica との通信(MathLink) について}
                    148:
                    149: CMO は 次のように変換されてから, MathLink を通して送られる.
                    150:
                    151: \begin{enumerate}
                    152: \item CMO\_INT32 は MLTKINT (多倍長整数型).
                    153: \item CMO\_STRING は MLTKSTR (文字列型).
1.4       ohara     154: \item CMO\_LIST は MLTKFUNC (関数型).
1.1       ohara     155: \item その他のタイプの CMO は ToExpression[文字列] として送る.
                    156: \end{enumerate}
                    157:
                    158: 上で述べられている ToExpression は Mathematica の組み込み関数であり,
                    159: 文字列を引数として Mathematica の式を返す.
                    160: (\cite[pp.407]{Wolfram-1996})
                    161:
                    162: ここで一つ注意をしておく.
                    163: MathLink では, int 型以外のデータを MLTKINT として送ることは残念ながらで
                    164: きない.  したがって CMO\_ZZ を直接, 整数型であると Mathematica に思わせ
                    165: ることはできないのである.  そこで, 次のような方法をとることになる.
                    166:
                    167: \begin{verbatim}
                    168: char *CONVERT_ZZ_TO_CSTRING(cmo_t zz);
                    169:
                    170: int main()
                    171: {
                    172:   char *s;
                    173:   cmo_t zz;  /* zz.tag == CMO_ZZ */
                    174:   MLINK lp;  /* MathLink Socket */
                    175:   ...
                    176:   s = CONVERT_ZZ_TO_CSTRING(zz);
                    177:   MLPutFunction(lp, "ToExpression", 1);
                    178:   MLPutString(lp, s);
                    179:   ...
                    180: }
                    181: \end{verbatim}
                    182:
                    183: このようにすると, Mathematica 側では, 例えば
                    184: \[
                    185: \mbox{\tt ToExpression["1234567890"]}
                    186: \]
                    187: という評価が行われ, 文字列データから整数が復元される.
                    188:
1.4       ohara     189: 逆に, Mathematica から送られた整数データは, マシン整数の範囲内であれば,
                    190: int として取得可能(MLGetInteger を使う)であるが, 受け取る前に int に収ま
                    191: るか否かを知ることはできない. int に収まらない場合、データが切り捨てられ
                    192: てしまうので注意が必要である.  また, 直接 CMO\_ZZ として取得することも不
                    193: 可能である.  (MathLink 上でどのような形式でデータ交換されているのかの情
                    194: 報は手元にある資料からは得られなかった)
1.1       ohara     195:
                    196: しかしながら, たとえ Mathematica 側から整数データが送られていたとしても,
                    197: そのデータを文字列に変換して受け取ることは MathLink の機構上可能である.
                    198:
                    199: これを利用して, 我々は次のようにして整数を受け取る.
                    200: \begin{verbatim}
                    201: cmo_t CONVERT_CSTRING_TO_ZZ(char *s);
                    202:
                    203: int main()
                    204: {
                    205:   MLINK lp;
                    206:   char *s;
                    207:   cmo_t zz;
                    208:   ...
                    209:   if(MLGetNext(lp) == MLTHINT) {
                    210:     MLGetString(lp, &s);
                    211:     zz = CONVERT_CSTRING_TO_ZZ(s);  /* zz.tag == CMO_ZZ */
                    212:   }
                    213:   ...
                    214: }
                    215: \end{verbatim}
                    216:
1.4       ohara     217: つまり、Mathematica から整数データを文字列として受け取り、その文字列を
                    218: OX サーバ側で CMO\_ZZ に直している。
1.1       ohara     219:
                    220: 基本的に MathLink では全てのデータを文字列で受け取るしか方法はない。どの
                    221: ような種類のデータであるかは受け取る前に知ることはできる。データの型は、
                    222: MLTKERR(エラー), MLTKINT(整数), MLTKSTR(文字列), MLREAL(実数), MLTKSYM
                    223: (シンボル), MLTKFUNC(関数) のいずれかである。このような事情で
                    224: Mathematica から受け取ったデータは基本的に CMO\_STRINGとしてスタックに積
                    225: まれるので、クライアント側でその文字列の解釈をする必要がでてくる。
                    226:
                    227: しかしながら、全ての MathLink オブジェクトが文字列に変換できるわけではな
                    228: いので、その取り扱いには注意を要する。
                    229: まだ、実装していないが、多項式(CMO\_???\_PORINOMIAL)の扱いが難しい。
                    230:
                    231: \section{個々のスタックマシン命令の実装}
1.6       ohara     232:
                    233: 現在、実装されているのは
1.1       ohara     234: SM\_popCMO, SM\_popString, SM\_pops, SM\_executeFunction,
                    235: SM\_executeStringByLocalParser, SM\_mathcap, SM\_setMathcap(受け取るだけ
                    236: で何もしない)である。
                    237:
1.8     ! ohara     238: \section{\oxmath への計算中断機能の実装}
        !           239:
        !           240: \noindent
        !           241: {\bf 注意: {\tt ox\_math\_interruption.tex}
        !           242: に Risa/Asir Conference (2003) での講演原稿がある.}
        !           243:
        !           244: OpenXM プロトコルは、エンジンに対して、計算中断機能を要求する。\oxmath
        !           245: のような wrapper プログラムでは、そのような機能を実装するのは一般には難
        !           246: しいが、MathLink には Mathematica Book~\cite{Wolfram-1996} に書かれてい
        !           247: ない機能があり(\cite{MathSource-Google1}, \cite{MathSource-Google2},
        !           248: \cite{Math-Output1})、そのひとつを用いて、\oxmath に計算中断機能を実装し
        !           249: た。この節では、その実装について説明する。
        !           250:
        !           251: Mathematica Kernel に対する割り込みは、
        !           252: \begin{enumerate}
        !           253: \item MLPutMessage で Mathematica Kernel に MLInterruptMessage を送る。
        !           254: \item 通信路の後始末を行い、最終的に ReturnPacket[\$Aborted] を受け取る。
        !           255: \end{enumerate}
        !           256: ことでなされる。
        !           257: MLPutMessage は MathLink の非公開関数でネットワーク透過性はない。
        !           258: Unix と Windows では異なるが、Unix の場合、MLInterruptMessage の実体は
        !           259: SIGINT である。
        !           260: 通信路の後始末には、{\bf Mathematica Kernel のバージョン依存性がある}ので、
        !           261: それを回避すると、結局、次の手順になる。
        !           262: \begin{enumerate}
        !           263: \item MLPutMessage(link, MLInterruptMessage)
        !           264: \item MenuPacket[1,"Interrupt> "] を受け取れば計算が中断されている
        !           265: \item MLPutString(link, "$\backslash$n")
        !           266: \item MenuPacket[0,"Interrupt> "] を受け取る
        !           267: \item MLPutString(link, "a")
        !           268: \item TextPacket["..."] を受け取る
        !           269: \item EvaluatePacket[0] を送って、ReturnPacket[...] をふたつ受け取る。
        !           270: 最初のものが ReturnPacket[\$Aborted] である。
        !           271: \end{enumerate}
        !           272:
        !           273: 最後の手順を説明する。
        !           274: ここで、ReturnPacket[\$Aborted] が素直に返ってくればいいのであるが、
        !           275: バージョン 3.x では返ってくるのに、バージョン4.xでは、何故か、
        !           276: 返ってこず、次の計算を行うとき、ふたつまとめて返ってくる。
        !           277: よって、ダミーにEvaluatePacket[0] を送るのである。
        !           278:
1.1       ohara     279: \section{Mathematica を OX のクライアントに}
1.6       ohara     280:
                    281: OpenXM クライアントは Mathematica の外部プログラム({\tt math2ox}) の形で
                    282: 実現されている。すなわち、Mathematica と math2ox の間は MathLink プロト
                    283: コルで、math2ox と OpenXM サーバの間は OpenXM プロトコルで通信し、
                    284: math2ox が適切に情報を変換しながらやりとりする。その意味で wrapper の一
                    285: 種であるとも言える。
1.1       ohara     286:
1.3       ohara     287: 利用するには、最初に
1.1       ohara     288: \begin{verbatim}
                    289: In[1]:= Install["math2ox"]
                    290: \end{verbatim}
1.3       ohara     291: として、math2ox をロードしなければならない。
                    292: Mathematica に新たに定義されるコマンドは、
1.5       ohara     293: {\tt OxStart[s\_String], OxStartInsecure[s\_String, p\_Integer, q\_Integer],
                    294: OxExecuteString[s\_String], OxParse[s\_String], OxGet[],
1.3       ohara     295: OxPopCMO[], OxPopString[], OxClose[], OxReset[]}
                    296: の9つである。
1.1       ohara     297:
1.3       ohara     298: math2ox をロードしたら、
1.1       ohara     299: \begin{verbatim}
                    300: In[2] := OxStart["ox_sm1"]
                    301: \end{verbatim}
1.3       ohara     302: によって OpenXM サーバに接続する。この場合の接続先は ox\_sm1 である。
                    303: もちろん
                    304: \begin{verbatim}
                    305: In[2] := OxStartInsecure["water.s.kanazawa-u.ac.jp", 1300, 1400]
                    306: \end{verbatim}
                    307: のようにして、insecure モードで接続してもよい。ただしこの場合は、
                    308: あらかじめ {\tt Run[]} 等で、OpenXM サーバを起動しておかなければならない。
                    309:
                    310: 接続が成功したらデータを送ってみよう。
                    311: \begin{verbatim}
                    312: In[3] := OxParse["(CMO_LIST, (CMO_STRING, "hello world"), (CMO_ZERO))"]
                    313: \end{verbatim}
                    314: のように CMO expression を指定することによって、
                    315: 任意の CMO を送信できる。
                    316: 正しくない CMO の場合には、何も送信されない。
                    317: また、CMO ではなく、
                    318: \begin{verbatim}
                    319: In[4] := OxParse["(OX_COMMAND, (SM_popCMO))"]
                    320: \end{verbatim}
                    321: などとして、OX メッセージの形で記述することもできる。
                    322: 注意しなければならないのは、SM コマンドの場合、OX スタックマシンから
                    323: OX メッセージが送られてくる場合があるが、OxParse[] を用いた場合、
                    324: このメッセージは自動的には受信しない(現在の仕様では)。したがって明示的に
                    325: 受信する必要がある。そのためには
                    326: \begin{verbatim}
1.5       ohara     327: In[5] := OxGet[]
1.3       ohara     328: \end{verbatim}
                    329: とするだけでよい。返ってくるオブジェクトは CMO に対応するものである。
                    330: \begin{verbatim}
                    331: In[6] := OxPopCMO[]
                    332: \end{verbatim}
1.5       ohara     333: を用いる場合にはもちろん {\tt OxGet[]} を呼び出す必要はない。
1.3       ohara     334:
                    335: 計算を実行するには {\tt OxExecute[]}
                    336: (SM\_executeStringByLocalParser) か、適切な OX メッセージを送信すること。
1.1       ohara     337:
1.3       ohara     338: 計算が終わったら、
1.1       ohara     339: \begin{verbatim}
1.3       ohara     340: In[7] := OxClose[]
1.1       ohara     341: \end{verbatim}
                    342: とすると、接続が終了する。
                    343:
                    344: \appendix
                    345: \section{付録}
                    346:
                    347: GMP における ``整数型'' {\tt mpz\_t} はつぎのような
                    348: 内部表現を持つ: \\
                    349: まず  {\tt mpz\_t} 型は
                    350: \begin{verbatim}
                    351: typedef struct __mpz_struct mpz_t[1];
                    352: \end{verbatim}
                    353: と typedef されており,
                    354: {\tt mpz\_t} 型の変数は(関数の仮引数でない限り)配列の
                    355: 扱いである. また,
                    356: \begin{verbatim}
                    357: typedef unsigned long int mp_limb_t;
                    358: \end{verbatim}
                    359: と宣言されている場合には,
                    360: 変数 {\tt mpz\_t x} の {\tt x->\_mp\_d} が unsigned long int の
                    361: 配列であり, データの実体である.
                    362: これは整数の最下位4バイトが配列の先頭にくる.
                    363: つまり全体としては``リトルエンディアンっぽい''が,
                    364: 各 unsigned long int はマシンのネイティブな integer である.
                    365: つまり, GMP の内部表現はマシン依存となっている.
                    366:
                    367: \begin{thebibliography}{99}
                    368: \bibitem{Openxxx-1998}
                    369: 野呂正行, 高山信毅.
1.4       ohara     370: {Open XM の設計と実装 --- Open message eXchange protocol for Mathematics},
1.8     ! ohara     371: November 22, 1999, Revised March 4, 2005.
1.1       ohara     372: \bibitem{Ohara-Takayama-Noro-1999}
                    373: 小原功任, 高山信毅, 野呂正行.
1.4       ohara     374: {Open asir 入門}, 1999, 数式処理, Vol 7, No 2, 2--17. (ISBN4-87243-086-7, SEG 出版, Tokyo).
1.1       ohara     375: \bibitem{Wolfram-1992}
                    376: ウルフラム.
                    377: {Mathematica (日本語版)},
                    378: アジソンウエスレイ, 1992.
                    379: \bibitem{Wolfram-1996}
                    380: Stephen Wolfram.
                    381: {The Mathematica Book}, Third edition,
                    382: Wolfram Media/Cambridge University Press, 1996.
                    383: \bibitem{miyachi-1998}
                    384: 宮地力.
                    385: {Mathematica によるネットワークプログラミング},
                    386: 岩波コンピュータサイエンス,
                    387: 岩波書店, 1998.
1.8     ! ohara     388: \bibitem{MathSource-Google1}
        !           389: Todd Gayley.
        !           390: [mg17015] in MathArchive,
        !           391: 1999 April.
        !           392: \bibitem{MathSource-Google2}
        !           393: 昔の MathLink にあった MLSignal の解説.
        !           394: (以前、Google のキャッシュにあったが、もうない)
        !           395: \bibitem{Math-Output1}
        !           396: mathlink.h, libMLa のシンボル表, mprep の生成するソース.
1.1       ohara     397: \end{thebibliography}
                    398:
                    399: \end{document}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>