1 <?xml version="1.0" encoding="UTF-8"?>
3     <refnamediv>
4         <refname>ode</refname>
5         <refpurpose>常微分方程式ソルバ</refpurpose>
6     </refnamediv>
7     <refsynopsisdiv>
8         <title>呼び出し手順</title>
9         <synopsis>y=ode(y0,t0,t,f)
10             [y,w,iw]=ode([type],y0,t0,t [,rtol [,atol]],f [,jac] [,w,iw])
11             [y,rd,w,iw]=ode("root",y0,t0,t [,rtol [,atol]],f [,jac],ng,g [,w,iw])
12             y=ode("discrete",y0,k0,kvect,f)
13         </synopsis>
14     </refsynopsisdiv>
15     <refsection>
16         <title>パラメータ</title>
17         <variablelist>
18             <varlistentry>
19                 <term>y0</term>
20                 <listitem>
21                     <para>実数ベクトルまたは行列 (初期条件).</para>
22                 </listitem>
23             </varlistentry>
24             <varlistentry>
25                 <term>t0</term>
26                 <listitem>
27                     <para>実数スカラー (初期時間).</para>
28                 </listitem>
29             </varlistentry>
30             <varlistentry>
31                 <term>t</term>
32                 <listitem>
33                     <para>実数ベクトル (解を計算する時間).</para>
34                 </listitem>
35             </varlistentry>
36             <varlistentry>
37                 <term>f</term>
38                 <listitem>
39                     <para>外部 (関数または文字列またはリスト).</para>
40                 </listitem>
41             </varlistentry>
42             <varlistentry>
43                 <term>type</term>
44                 <listitem>
45                     <para>
47                         <literal>"stiff"</literal>, <literal>"rk"</literal>,
48                         <literal>"rkf"</literal>, <literal>"fix"</literal>,
49                         <literal>"discrete"</literal>, <literal>"roots"</literal>.
50                     </para>
51                 </listitem>
52             </varlistentry>
53             <varlistentry>
54                 <term>rtol, atol</term>
55                 <listitem>
56                     <para>
57                         実数定数または<literal>y</literal>と同じ大きさの実数ベクトル.
58                     </para>
59                 </listitem>
60             </varlistentry>
61             <varlistentry>
62                 <term>jac</term>
63                 <listitem>
64                     <para>外部 (関数または文字列またはリスト).</para>
65                 </listitem>
66             </varlistentry>
67             <varlistentry>
68                 <term>w, iw</term>
69                 <listitem>
70                     <para>実数ベクトル.</para>
71                 </listitem>
72             </varlistentry>
73             <varlistentry>
74                 <term>ng</term>
75                 <listitem>
76                     <para>整数.</para>
77                 </listitem>
78             </varlistentry>
79             <varlistentry>
80                 <term>g</term>
81                 <listitem>
82                     <para>外部 (関数または文字列またはリスト).</para>
83                 </listitem>
84             </varlistentry>
85             <varlistentry>
86                 <term>k0</term>
87                 <listitem>
88                     <para>整数 (初期時間).</para>
89                 </listitem>
90             </varlistentry>
91             <varlistentry>
92                 <term>kvect</term>
93                 <listitem>
94                     <para>整数ベクトル.</para>
95                 </listitem>
96             </varlistentry>
97         </variablelist>
98     </refsection>
99     <refsection>
100         <title>説明</title>
101         <para>
102             <literal>ode</literal> は,dy/dt=f(t,y) , y(t0)=y0で定義された
103             明示的なODEシステムを解くための標準関数です.
104             この関数は,種々のソルバ,特に ODEPACKへのインターフェイスです.
105             解く問題の型と使用される手法は最初のオプション引数<literal>type</literal>
106             の値に依存します.
107             <literal>type</literal>は,以下の文字列のどれかになります:
108         </para>
109         <variablelist>
110             <varlistentry>
111                 <term>&lt;not given&gt;:</term>
112                 <listitem>
113                     <para>
114                         パッケージODEPACKの<literal>lsoda</literal> ソルバが
115                         デフォルトでコールされます.
117                         後退差分法(BDF)を自動的に選択します.
118                         まず非スティッフな手法が使用され,使用する手法を
119                         決定するためにデータを動的にモニタします.
120                     </para>
121                 </listitem>
122             </varlistentry>
123             <varlistentry>
125                 <listitem>
126                     <para>これは非スティッフな問題用です. ODEPACKパッケージの
127                         <literal>lsode</literal> ソルバがコールされ, この関数は
129                     </para>
130                 </listitem>
131             </varlistentry>
132             <varlistentry>
133                 <term>"stiff":</term>
134                 <listitem>
135                     <para>これはスティッフな問題用です. ODEPACKパッケージの
136                         <literal>lsode</literal> ソルバがコールされ, BDF法が使用されます.
137                     </para>
138                 </listitem>
139             </varlistentry>
140             <varlistentry>
141                 <term>"rk":</term>
142                 <listitem>
143                     <para>4次の適応型 Runge-Kutta (RK4) 法.</para>
144                 </listitem>
145             </varlistentry>
146             <varlistentry>
147                 <term>"rkf":</term>
148                 <listitem>
149                     <para>
150                         Fehlbergの4次と5次の Runge-Kutta法に基づくShampine および Wattsのプログラム
151                         (RKF45) が使用されます.
152                         この方法は非スティッフおよびややスティッフな問題用で,
153                         微係数の評価コストが低い場合に適しています.
154                         この手法は一般にユーザが高い精度を望む場合には使用するべきではありません.
155                     </para>
156                 </listitem>
157             </varlistentry>
158             <varlistentry>
159                 <term>"fix":</term>
160                 <listitem>
161                     <para>
162                         <literal>"rkf"</literal>と同じソルバですがユーザインターフェイスが非常にシンプルで,
163                         <literal>rtol</literal> および <literal>atol</literal>パラメータのみを
164                         ソルバに指定することが可能です.
165                         この手法は使用できる中で最も簡単な手法です.
166                     </para>
167                 </listitem>
168             </varlistentry>
169             <varlistentry>
170                 <term>"root":</term>
171                 <listitem>
172                     <para>解を得る機能を有するODE ソルバ. ODEPACKパッケージの
173                         <literal>lsodar</literal> ソルバが使用されます.
174                         使用されているのは<literal>lsoda</literal> ソルバを改変したもので,
175                         指定したベクトル関数の根を見つけることができます.
177                     </para>
178                 </listitem>
179             </varlistentry>
180             <varlistentry>
181                 <term>"discrete":</term>
182                 <listitem>
183                     <para>
185                     </para>
186                 </listitem>
187             </varlistentry>
188         </variablelist>
189         <para>
190             このヘルプでは,標準的な陽のODEシステムに関する<literal>ode</literal>
191             の使用法のみについて記述します.
192         </para>
193         <itemizedlist>
194             <listitem>
195                 <para>
196                     <literal>ode</literal>の最も簡単なコールは次のようになります:
197                     <literal>y=ode(y0,t0,t,f)</literal> ただし <literal>y0</literal> は
198                     初期条件のベクトル,<literal>t0</literal> は初期時間,
199                     <literal>t</literal> は解<literal>y</literal>を計算する時間のベクトル,
200                     <literal>y</literal>は解ベクトルの行列<literal>y=[y(t(1)),y(t(2)),...]</literal>
201                     です.
202                 </para>
203                 <para>
204                     入力引数 <literal>f</literal> は1次微分方程式
205                     dy/dt=f(t,y)のRHSを定義します.
206                     これは外部,すなわち指定した構文の関数または指定したコール手続きを
207                     有するFortranサブルーチンまたはC関数の名前(文字列),またはリストです:
208                 </para>
209                 <itemizedlist>
210                     <listitem>
211                         <para>
212                             <literal>f</literal> が Scilab 関数の場合,
213                             その構文は <literal>ydot = f(t,y)</literal>となります.
214                             ただし,<literal>t</literal>は実数スカラー(時間),
215                             <literal>y</literal> は実数ベクトル (状態量),
216                             <literal>ydot</literal>は実数ベクトル (dy/dt)です.
217                         </para>
218                     </listitem>
219                     <listitem>
220                         <para>
221                             <literal>f</literal> が文字列の場合,
222                             FortranサブルーチンまたはC関数の名前が参照されます.
223                             すなわち,<literal>ode(y0,t0,t,"fex")</literal>がコマンドの
224                             場合,サブルーチン<literal>fex</literal>がコールされます.
225                         </para>
226                         <para>Fortranルーチンは以下の呼び出し手順とする
227                             必要があります: <literal>fex(n,t,y,ydot)</literal>,
228                             ただし n は整数, t は倍精度実数, y と ydot は倍精度ベクトルです.
229                         </para>
230                         <para>C 関数は以下のプロトタイプとする必要があります:
231                             <literal>fex(int *n,double *t,double *y,double
232                                 *ydot)
233                             </literal>
234                         </para>
235                         <para>
236                             <literal>t</literal> は時間, <literal>y</literal> は
237                             状態量, <literal>ydot</literal>は状態量の微分
238                             (dy/dt)です.
239                         </para>
240                         <para>This external can be build in a OS independant way using
243                             function.
244                         </para>
245                     </listitem>
246                     <listitem>
247                         <para>
248                             引数<literal>f</literal> は以下の構造を有するリストと
249                             することもできます:
250                             <literal>lst=list(realf,u1,u2,...un)</literal> ただし,
251                             <literal>realf</literal> は次の構文を有するScilab関数です:
252                             <literal>ydot = f(t,y,u1,u2,...,un)</literal>
253                         </para>
254                         <para>この構文により
255                             <literal>realf</literal>の引数にパラメータを使用することができます.
256                         </para>
257                     </listitem>
258                 </itemizedlist>
259                 <para>
260                     関数 <literal>f</literal> はベクトルではなく <literal>p x
261                         q
262                     </literal>
263                     の行列を返すことができます. この行列表記により,
264                     <literal>n=p+q</literal> 次のODEシステム<literal>dY/dt=F(t,Y)</literal>
265                     を解きます.
266                     ただし, <literal>Y</literal>は <literal>p x q</literal>の行列です.
267                     初期条件 <literal>Y0</literal>も<literal>p x q</literal>の行列
268                     である必要があり, <literal>ode</literal>の結果は <literal>p x
269                         q(T+1)
270                     </literal>
271                     の行列 <literal>[Y(t_0),Y(t_1),...,Y(t_T)]</literal>
272                     となります.
273                 </para>
274             </listitem>
275             <listitem>
276                 <para>オプションの入力パラメータとして次の
277                     解の誤差を指定できます:
278                     相対および絶対推定誤差の閾値である
279                     <literal>rtol</literal> および <literal>atol</literal>.
280                     <literal>y(i)</literal>の指定誤差は次のようになります:
281                     <literal>rtol(i)*abs(y(i))+atol(i)</literal>
282                 </para>
283                 <para>そして,状態量の全ての要素に関してこの誤差が小さい場合,
284                     積分が行われます.
285                     <literal>rtol</literal> または
286                     <literal>atol</literal> が一つの定数の場合, <literal>rtol(i)</literal>
287                     および <literal>atol(i)</literal> はこの定数の値に設定されます.
288                     <literal>rtol</literal> および <literal>atol</literal>のデフォルト値は
289                     多くのソルバではそれぞれ<literal>rtol=1.d-5</literal> および
290                     <literal>atol=1.d-7</literal>,
291                     <literal>"rfk"</literal> および <literal>"fix"</literal>では
292                     <literal>rtol=1.d-3</literal> および <literal>atol=1.d-4</literal>です.
293                 </para>
294             </listitem>
295             <listitem>
296                 <para>スティッフな問題の場合, RHS関数のヤコビアンを
297                     オプションの引数<literal>jac</literal>として
298                     指定する方が良いでしょう.
299                     これは,外部,すなわち,指定された構文を有する関数,
300                     または指定した呼び出し手順を有するFortranサブルーチンまたは
301                     C関数の名前(文字列),またはリストです.
302                 </para>
303                 <para>
304                     <literal>jac</literal> が関数の場合,
305                     構文は
306                     <literal>J=jac(t,y)</literal>とする必要があります.
307                 </para>
308                 <para>
309                     ただし, <literal>t</literal> は実数スカラー (時間)および
310                     <literal>y</literal> 実数ベクトル (状態量). 結果の行列
311                     <literal>J</literal> は df/dx を評価する必要があります.
312                     ただし, <literal>J(k,i) =dfk/dxi</literal> で <literal>fk</literal> は
313                     fのk番目の要素です.
314                 </para>
315                 <para>
316                     <literal>jac</literal> は文字列で,
317                     FortranサブルーチンまたはC関数の名前を指し,
318                     以下の呼び出し手順となります:
319                 </para>
320                 <para>Fortranの場合:</para>
321                 <programlisting role=""><![CDATA[
322 subroutine fex(n,t,y,ml,mu,J,nrpd)
323 integer n,ml,mu,nrpd
324 double precision t,y(*),J(*)
325  ]]></programlisting>
326                 <para>Cの場合:</para>
327                 <programlisting role=""><![CDATA[
328 void fex(int *n,double *t,double *y,int *ml,int *mu,double *J,int *nrpd,)
329  ]]></programlisting>
330                 <para>
331                     <literal>jac(n,t,y,ml,mu,J,nrpd)</literal>. 多くの場合,
332                     <literal>ml</literal>,<literal>mu</literal>および
333                     <literal>nrpd</literal>を参照するべきではありません.
334                 </para>
335                 <para>
336                     <literal>jac</literal> がリストの場合,
337                     <literal>f</literal>と同じ同じ構文が適用されます.
338                 </para>
339             </listitem>
340             <listitem>
341                 <para>
342                     オプションの引数 <literal>w</literal> および
343                     <literal>iw</literal> は積分ルーチンにより返される情報を
345                     これらのベクトルが<literal>ode</literal>のRHSで提供される場合,
346                     積分は前回の停止時と同じパラメータで再開されます.
347                 </para>
348             </listitem>
349             <listitem>
350                 <para>
351                     より多くのオプションを<literal>%ODEOPTIONS</literal>変数
352                     によりODEPACKソルバに指定することができます.
354                 </para>
355             </listitem>
356         </itemizedlist>
357     </refsection>
358     <refsection>
359         <title>例</title>
360         <programlisting role="example"><![CDATA[
361 // ---------- Simple one dimension ODE (Scilab function external)
362 // dy/dt=y^2-y sin(t)+cos(t), y(0)=0
363 function ydot=f(t,y),ydot=y^2-y*sin(t)+cos(t),endfunction
364 y0=0;t0=0;t=0:0.1:%pi;
365 y=ode(y0,t0,t,f)
366 plot(t,y)
368 // ---------- Simple one dimension ODE (C coded external)
369 ccode=['#include <math.h>'
370        'void myode(int *n,double *t,double *y,double *ydot)'
371        '{'
372        '  ydot[0]=y[0]*y[0]-y[0]*sin(*t)+cos(*t);'
373        '}']
374 mputl(ccode,TMPDIR+'/myode.c') //create the C file
377 y0=0;t0=0;t=0:0.1:%pi;
378 y=ode(y0,t0,t,'myode');
380 // ---------- Simulation of dx/dt = A x(t) + B u(t) with u(t)=sin(omega*t),
381 // x0=[1;0]
382 // solution x(t) desired at t=0.1, 0.2, 0.5 ,1.
383 // A and u function are passed to RHS function in a list.
384 // B and omega are passed as global variables
385 function xdot=linear(t,x,A,u),xdot=A*x+B*u(t),endfunction
386 function ut=u(t),ut=sin(omega*t),endfunction
387 A=[1 1;0 2];B=[1;1];omega=5;
388 ode([1;0],0,[0.1,0.2,0.5,1],list(linear,A,u))
390 // ---------- Matrix notation Integration of the Riccati differential equation
391 // Xdot=A'*X + X*A - X'*B*X + C , X(0)=Identity
392 // Solution at t=[1,2]
393 function Xdot=ric(t,X),Xdot=A'*X+X*A-X'*B*X+C,endfunction
394 A=[1,1;0,2]; B=[1,0;0,1]; C=[1,0;0,1];
395 t0=0;t=0:0.1:%pi;
396 X=ode(eye(A),0,t,ric)
398 // ---------- Matrix notation, Computation of exp(A)
399 A=[1,1;0,2];
400 function xdot=f(t,x),xdot=A*x;,endfunction
401 ode(eye(A),0,1,f)
404 // ---------- Matrix notation, Computation of exp(A) with stiff matrix, Jacobian given
405 A=[10,0;0,-1];
406 function xdot=f(t,x),xdot=A*x,endfunction
407 function J=Jacobian(t,y),J=A,endfunction
408 ode("stiff",[0;1],0,1,f,Jacobian)
409  ]]></programlisting>
410     </refsection>
411     <refsection role="see also">
412         <title>参照</title>
413         <simplelist type="inline">
414             <member>
416             </member>
417             <member>
419             </member>
420             <member>
422             </member>
423             <member>
425             </member>
426             <member>
428             </member>
429             <member>
431             </member>
432             <member>
434             </member>
435             <member>
437             </member>
438             <member>
440             </member>
441             <member>
443             </member>
444         </simplelist>
445     </refsection>
446     <refsection>
447         <title>参考文献</title>
448         <para>Alan C. Hindmarsh, lsode and lsodi, two new initial value ordinary
449             differential equation solvers, acm-signum newsletter, vol. 15, no. 4
450             (1980), pp. 10-11.
451         </para>
452     </refsection>
453     <refsection>
454         <title>使用される関数</title>
455         <para>関連する関数は SCI/modules/differential_equations/src/fortran directory
456             :
457         </para>
458         <para>lsode.f lsoda.f lsodar.f です.</para>
459     </refsection>
460 </refentry>