1 <?xml version="1.0" encoding="UTF-8"?>
3 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
4 * Copyright (C) 2008 - INRIA
5 * Copyright (C) 2011 - DIGITEO - Michael Baudin
6 * Copyright (C) 2012 - Scilab Enterprises - Adeline CARNIS
8 * Copyright (C) 2012 - 2016 - Scilab Enterprises
10 * This file is hereby licensed under the terms of the GNU GPL v2.0,
11 * pursuant to article 5.3.4 of the CeCILL v.2.1.
12 * This file was originally licensed under the terms of the CeCILL v2.1,
13 * and continues to be available under such terms.
14 * For more information, see the COPYING file which you should have received
15 * along with this program.
18 <refentry xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns5="http://www.w3.org/1999/xhtml" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:db="http://docbook.org/ns/docbook" xmlns:scilab="http://www.scilab.org" xml:id="ode" xml:lang="en">
20 <refname>ode</refname>
21 <refpurpose>ordinary differential equation solver</refpurpose>
27 [y, w, iw] = ode([type,] y0, t0, t [,rtol [,atol]], f [,jac] [,w, iw])
28 [y, rd, w, iw] = ode("root", y0, t0, t [,rtol [,atol]], f [,jac],ng, g [,w,iw])
29 y = ode("discrete", y0, k0, kvect, f)
33 <title>Arguments</title>
38 <para>a real vector or matrix, the initial conditions.</para>
45 a real scalar, the initial time.
53 a real vector, the times at which the solution is computed.
61 a function, external, string or list, the right hand side of
62 the differential equation.
70 a string, the solver to use. The available solvers are
71 <literal>"adams"</literal>,
72 <literal>"stiff"</literal>, <literal>"rk"</literal>,
73 <literal>"rkf"</literal>, <literal>"fix"</literal>,
74 <literal>"discrete"</literal>, <literal>"roots"</literal>.
82 a real constant or real vector of the same size as
83 <varname>y</varname>, the relative tolerance.
91 a real constant or real vectors of the same size as
92 <varname>y</varname>, the absolute tolerance.
100 a function, external, string or list, the Jacobian of the
101 function <varname>f</varname>.
108 <para>real vectors. (INPUT/OUTPUT)</para>
114 <para>an integer.</para>
120 <para>an external (function or character string or list).</para>
126 <para>an integer (initial time).</para>
132 <para>an integer vector.</para>
138 <para>a real vector or matrix. (OUTPUT)</para>
144 <para>a real vector. (OUTPUT)</para>
150 <title>Description</title>
152 <function>ode</function> solves explicit Ordinary Different Equations defined by:
158 \dfrac{dy}{dt} = f(t,y)\\
165 It is an interface to various solvers, in particular to ODEPACK.
168 In this help, we only describe the use of <function>ode</function> for
169 standard explicit ODE systems.
172 The simplest call of <function>ode</function> is:
173 <literal>y = ode(y0,t0,t,f)</literal> where <literal>y0</literal> is the
174 vector of initial conditions, <literal>t0</literal> is the initial
175 time, <literal>t</literal> is the vector of times at which the
176 solution <varname>y</varname> is computed and <varname>y</varname> is
177 matrix of solution vectors
178 <literal>y=[y(t(1)),y(t(2)),...]</literal>.
181 The input argument <varname>f</varname> defines the right hand side of the
182 first order differential equation. This argument is a function with a specific header.
187 If <varname>f</varname> is a Scilab function, its syntax
194 where <literal>t</literal> is a real scalar (the time) and
195 <varname>y</varname> is a real vector (the state) and
196 <literal>ydot</literal> is a real vector (the first order derivative
202 If <varname>f</varname> is a string, it is
203 the name of a Fortran subroutine or a C compiled function. For example, if
204 we call <literal>ode(y0,t0,t,"fex")</literal>, then the
205 subroutine <literal>fex</literal> is called.
208 The Fortran routine must have the header:
214 where <literal>n</literal> is an integer, <literal>t</literal> is
215 a double precision scalar, <varname>y</varname> and
216 <literal>ydot</literal> are double precision
220 The C function must have the header:
223 fex(int *n,double *t,double *y,double *ydot)
226 where <literal>t</literal> is the time, <varname>y</varname> the
227 state and <literal>ydot</literal> is the state derivative
231 This external can be build in a OS independent way using
232 <link linkend="ilib_for_link">ilib_for_link</link> and dynamically
233 linked to Scilab by the <link linkend="link">link</link>
239 It may happen that the simulator <varname>f</varname> needs extra
241 In this case, we can use the following feature.
242 The <varname>f</varname> argument can also be a list
243 <literal>lst=list(simuf,u1,u2,...un)</literal> where
244 <literal>simuf</literal> is a Scilab function with syntax:
245 <literal>ydot = f(t,y,u1,u2,...,un)</literal>
246 and <literal>u1</literal>, <literal>u2</literal>, ...,
247 <literal>un</literal> are extra arguments which are automatically
248 passed to the simulator <literal>simuf</literal>.
253 The function <varname>f</varname> can return a p-by-q matrix instead of a vector.
254 With this matrix notation, we
255 solve the <literal>n=p+q</literal> ODE's system
256 <literal>dY/dt=F(t,Y)</literal> where <literal>Y</literal> is a
257 <literal>p x q</literal> matrix. Then initial conditions,
258 <literal>Y0</literal>, must also be a <literal>p x q</literal> matrix
259 and the result of <function>ode</function> is the <literal>p-by-q(T+1)</literal> matrix
260 <literal>[Y(t_0),Y(t_1),...,Y(t_T)]</literal>.
263 The tolerances <varname>rtol</varname> and <varname>atol</varname> are
264 thresholds for relative and absolute estimated errors. The estimated
265 error on <literal>y(i)</literal> is:
266 <literal>rtol(i)*abs(y(i))+atol(i)</literal>
267 and integration is carried out as far as this error is small for
268 all components of the state. If <varname>rtol</varname> and/or
269 <varname>atol</varname> is a constant <literal>rtol(i)</literal>
270 and/or <literal>atol(i)</literal> are set to this constant value.
271 Default values for <varname>rtol</varname> and <varname>atol</varname>
272 are respectively <literal>rtol=1.d-5</literal> and
273 <literal>atol=1.d-7</literal> for most solvers and
274 <literal>rtol=1.d-3</literal> and <literal>atol=1.d-4</literal> for
275 <literal>"rfk"</literal> and <literal>"fix"</literal>.
278 For stiff problems, it is better to give the Jacobian of the RHS
279 function as the optional argument <varname>jac</varname>.
280 The Jacobian is an external i.e. a function with specified syntax, or the name of a
281 Fortran subroutine or a C function (character string) with specified
282 calling sequence or a list.
287 If <varname>jac</varname> is a function the syntax should be
288 <literal>J=jac(t,y)</literal> where <literal>t</literal> is a real
289 scalar (time) and <varname>y</varname> a real vector (state).
290 The result matrix <literal>J</literal> must evaluate to df/dx i.e.
291 <literal>J(k,i) = dfk/dxi</literal> where <literal>fk</literal> is the
292 <literal>k</literal>-th component of <varname>f</varname>.
297 If <varname>jac</varname> is a character string it refers to the
298 name of a Fortran subroutine or a C function.
301 The Fortran routine must have the header:
304 subroutine fex(n,t,y,ml,mu,J,nrpd)
306 double precision t,y(*),J(*)
309 The C function must have the header:
312 void fex(int *n,double *t,double *y,int *ml,int *mu,double *J,int *nrpd,)
315 In most cases you have not to refer <literal>ml</literal>, <literal>mu</literal> and
316 <literal>nrpd</literal>.
321 If <varname>jac</varname> is a list the same conventions as for
322 <varname>f</varname> apply.
327 Optional arguments <varname>w</varname> and
328 <varname>iw</varname> are vectors for storing information returned by
329 the integration routine (see <link linkend="ode_optional_output">ode_optional_output</link> for details).
330 When these vectors are provided in RHS of <function>ode</function> the
331 integration re-starts with the same parameters as in its previous
335 More options can be given to ODEPACK solvers by using
336 <literal>%ODEOPTIONS</literal> variable. See <link linkend="odeoptions">odeoptions</link>.
340 <title>The solvers</title>
342 The type of problem solved and
343 the method used depend on the value of the first optional argument
344 <varname>type</varname> which can be one of the following strings:
348 <term><not given>:</term>
351 <literal>lsoda</literal> solver of package ODEPACK is called
352 by default. It automatically selects between nonstiff
353 predictor-corrector Adams method and stiff Backward Differentiation
354 Formula (BDF) method. It uses nonstiff method initially and
355 dynamically monitors data in order to decide which method to
361 <term>"adams":</term>
364 This is for nonstiff problems. <literal>lsode</literal> solver
365 of package ODEPACK is called and it uses the Adams method.
370 <term>"stiff":</term>
373 This is for stiff problems. <literal>lsode</literal> solver of
374 package ODEPACK is called and it uses the BDF method.
381 <para>Adaptive Runge-Kutta of order 4 (RK4) method.</para>
388 The Shampine and Watts program based on Fehlberg's Runge-Kutta
389 pair of order 4 and 5 (RKF45) method is used. This is for non-stiff
390 and mildly stiff problems when derivative evaluations are
391 inexpensive. This method should generally not be used when the user
392 is demanding high accuracy.
400 Same solver as <literal>"rkf"</literal>, but the user interface
402 i.e. only <varname>rtol</varname> and <varname>atol</varname>
403 parameters can be passed to the solver. This is the simplest method
412 ODE solver with rootfinding capabilities. The
413 <literal>lsodar</literal> solver of package ODEPACK is used. It is a
414 variant of the <literal>lsoda</literal> solver where it finds the
415 roots of a given vector function. See help on <link linkend="ode_root">ode_root</link> for more
421 <term>"discrete":</term>
424 Discrete time simulation. See help on
425 <link linkend="ode_discrete">ode_discrete</link> for more
433 <title>Examples</title>
435 In the following example, we solve the Ordinary Differential Equation
436 <literal>dy/dt=y^2-y*sin(t)+cos(t)</literal> with the initial
437 condition <literal>y(0)=0</literal>.
438 We use the default solver.
440 <programlisting role="example"><![CDATA[
442 ydot=y^2-y*sin(t)+cos(t)
452 ydot=y^2-y*sin(t)+cos(t)
461 In the following example, we solve the equation <literal>dy/dt=A*y</literal>.
462 The exact solution is <literal>y(t)=expm(A*t)*y(0)</literal>, where
463 <literal>expm</literal> is the matrix exponential.
464 The unknown is the 2-by-1 matrix y(t).
466 <programlisting role="example"><![CDATA[
470 function J=Jacobian(t,y)
477 ode("stiff",y0,t0,t,f,Jacobian)
478 // Compare with exact solution:
482 In the following example, we solve the ODE <literal>dx/dt = A x(t) + B u(t)</literal>
483 with <literal>u(t)=sin(omega*t)</literal>.
484 Notice the extra arguments of <varname>f</varname>:
485 <literal>A</literal>, <literal>u</literal>, <literal>B</literal>,
486 <literal>omega</literal> are passed to function <varname>f</varname> in a list.
488 <programlisting role="example"><![CDATA[
489 function xdot=linear(t,x,A,u,B,omega)
490 xdot=A*x+B*u(t,omega)
492 function ut=u(t,omega)
501 ode(y0,t0,t,list(linear,A,u,B,omega))
504 In the following example, we solve the Riccati differential equation
505 <literal>dX/dt=A'*X + X*A - X'*B*X + C</literal> where initial
506 condition <literal>X(0)</literal> is the 2-by-2 identity matrix.
508 <programlisting role="example"><![CDATA[
509 function Xdot=ric(t,X,A,B,C)
510 Xdot=A'*X+X*A-X'*B*X+C
518 X = ode(y0,t0,t,list(ric,A,B,C))
521 In the following example, we solve the differential equation
522 <literal>dY/dt=A*Y</literal> where the unknown <literal>Y(t)</literal>
524 The exact solution is <literal>Y(t)=expm(A*t)</literal>, where
525 <literal>expm</literal> is the matrix exponential.
527 <programlisting role="example"><![CDATA[
528 function ydot=f(t,y,A)
535 ode(y0,t0,t,list(f,A))
536 // Compare with the exact solution:
538 ode("adams",y0,t0,t,f)
542 <title>With a compiler</title>
544 The following example requires a C compiler.
546 <programlisting role="example"><![CDATA[
547 // ---------- Simple one dimension ODE (C coded external)
548 ccode=['#include <math.h>'
549 'void myode(int *n,double *t,double *y,double *ydot)'
551 ' ydot[0]=y[0]*y[0]-y[0]*sin(*t)+cos(*t);'
553 mputl(ccode,TMPDIR+'/myode.c') //create the C file
555 ilib_for_link('myode','myode.c',[],'c',[],TMPDIR+'/loader.sce');
556 exec(TMPDIR+'/loader.sce') //incremental linking
560 y = ode(y0,t0,t,'myode');
564 <refsection role="see also">
565 <title>See Also</title>
566 <simplelist type="inline">
568 <link linkend="ode_discrete">ode_discrete</link>
571 <link linkend="ode_root">ode_root</link>
574 <link linkend="dassl">dassl</link>
577 <link linkend="impl">impl</link>
580 <link linkend="odedc">odedc</link>
583 <link linkend="odeoptions">odeoptions</link>
586 <link linkend="csim">csim</link>
589 <link linkend="ltitr">ltitr</link>
592 <link linkend="rtitr">rtitr</link>
595 <link linkend="intg">intg</link>
600 <title>Bibliography</title>
602 Alan C. Hindmarsh, "lsode and lsodi, two new initial value ordinary
603 differential equation solvers", ACM-Signum newsletter, vol. 15, no. 4
608 <title>Used Functions</title>
610 The associated routines can be found in SCI/modules/differential_equations/src/fortran directory:
611 lsode.f lsoda.f lsodar.f