<?xml version="1.0" encoding="UTF-8"?>
<!--
 * Scilab ( https://www.scilab.org/ ) - This file is part of Scilab
 * Copyright (C) 2008 - INRIA
 * ...
 *
 * Copyright (C) 2012 - 2016 - Scilab Enterprises
 *
 * This file is hereby licensed under the terms of the GNU GPL v2.0,
 * pursuant to article 5.3.4 of the CeCILL v.2.1.
 * This file was originally licensed under the terms of the CeCILL v2.1,
 * and continues to be available under such terms.
 * For more information, see the COPYING file which you should have received
 * along with this program.
 *
 -->
<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="odedc" xml:lang="en">
    <refnamediv>
        <refname>odedc</refname>
        <refpurpose>discrete/continuous ode solver</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <title>Syntax</title>
        <synopsis>yt = odedc(y0, nd, stdel, t0, t, f)</synopsis>
    </refsynopsisdiv>
    <refsection role="parameters">
        <title>Arguments</title>
        <variablelist>
            <varlistentry>
                <term>y0</term>
                <listitem>
                    <para>a real column vector (initial conditions),
                        <literal>y0=[y0c;y0d]</literal> where <literal>y0d</literal> has
                        <literal>nd</literal> components.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>nd</term>
                <listitem>
                    <para>
                        an integer, dimension of <literal>y0d</literal>
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>stdel</term>
                <listitem>
                    <para>
                        a real vector with one or two entries, <literal>stdel=[h, delta]</literal>
                        (with <literal>delta=0</literal> as default value).
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>t0</term>
                <listitem>
                    <para>a real scalar (initial time).</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>t</term>
                <listitem>
                    <para>
                        a real (row) vector, instants where <literal>yt</literal> is
                        calculated.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>f</term>
                <listitem>
                    <para>an external i.e. a function or a character string or a list with
                        syntax: <literal>yp = f(t,yc,yd,flag)</literal>.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>f</term>
                <listitem>
                    <para>
                        an <link linkend="external" role="" version="">external</link> i.e. a
                        function or a character string or a list with
                        syntax: <literal>yp = f(t,yc,yd,flag)</literal>
                    </para>
                    <variablelist>
                        <varlistentry>
                            <term>a list</term>
                            <listitem>
                                <para>This form of external is used to pass parameters to the
                                    function. It must be as follows:
                                </para>
                                <screen><![CDATA[
list(f, p1, p2,...)
]]></screen>
                                <para>where the syntax of the function
                                    <literal>f</literal> is now
                                </para>
                                <screen><![CDATA[
yp = f(t, yc, yd, flag, p1, p2,...)
]]></screen>
                                <para>
                                    <literal>f</literal> still returns the function value
                                    as a function of <literal>(t, yc, yd, flag, p1, p2,...)</literal>, and
                                    <literal>p1, p2,...</literal> are function parameters.
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>a character string</term>
                            <listitem>
                                <para>
                                    it must refer to the name of a C or fortran routine,
                                    assuming that &lt;<literal>f_name</literal>&gt; is the given name.
                                </para>
                                <itemizedlist>
                                    <listitem>
                                        <para>
                                            The Fortran calling sequence must be
                                        </para>
                                        <para>
                                            <literal>&lt;f_name&gt;(iflag, nc, nd, t, y, ydp)</literal>
                                        </para>
                                        <para>
                                            <literal>double precision t, y(*), ydp(*)
                                            </literal>
                                        </para>
                                        <para>
                                            <literal>integer iflag, nc, nd</literal>
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>The C syntax must be</para>
                                        <para>
                                            <literal>void &lt;f_name&gt; (int *iflag, int *nc,
                                                int *nd, double *t, double *y, double *ydp)
                                            </literal>
                                        </para>
                                    </listitem>
                                </itemizedlist>
                                <para>In both Fortran and C cases, the input arguments are:</para>
                                <itemizedlist>
                                    <listitem>
                                        <para>
                                            <literal>iflag</literal> = <literal>0</literal> or <literal>1</literal>
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <literal>nc</literal> = number of continuous states <literal>yc</literal>
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <literal>nd</literal> = number of discrete states <literal>yd</literal>
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <literal>t</literal> = time
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <literal>y</literal> = <literal>[yc; yd; param]</literal>.
                                            param may be used to get extra arguments which have
                                            been given in  the odedc call
                                           <literal>(y = odedc([y0c; y0d], nd, stdel, t0, t, list('fexcd', param)))</literal>
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            As output <literal>ydp</literal>, the routine must
                                            compute <literal>ydp[0:nc-1] = d/dt ( yc(t) )</literal>
                                            for <literal>iflag=0</literal> and
                                            <literal>ydp[0:nd-1] = yd(t+)</literal>
                                            for <literal>iflag=1</literal>.
                                        </para>
                                    </listitem>
                                </itemizedlist>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection role="description">
        <title>Description</title>
        <para>
            <literal>y = odedc([y0c;y0d], nd, [h,delta], t0, t, f)</literal> computes
            the solution of a mixed discrete/continuous system. The discrete system
            state <literal>yd<subscript>k</subscript></literal> is embedded into a piecewise constant
            <literal>yd(t)</literal> time function as follows:
        <literal>yd(t) = yd<subscript>k</subscript></literal> for <literal>t</literal> in
        <literal>[t<subscript>k</subscript> = h*(delta+k) , t<subscript>k+1</subscript> = h*(delta+k+1) )</literal>.
        </para>
        <para>
            The simulated equations are now,
            for t in [ t<subscript>k</subscript> , t<subscript>k+1</subscript> ):
        </para>
        <screen>
dyc/dt = f(t, yc(t), yd(t), 0)
yc(t0) = y0c
</screen>
        <para>
            and at instants <literal>t<subscript>k</subscript></literal> the discrete variable
            <literal>yd</literal> is updated by
        </para>
        <para>
            <literal>yd(t<subscript>k+</subscript>)
            = f(yc(t<subscript>k-</subscript>), yd(t<subscript>k-</subscript>), 1)</literal>.
        </para>
            <para>
            Note that, using the definition of <literal>yd(t)</literal> the last
            equation gives
        </para>
        <para>
            <literal>yd<subscript>k</subscript>
            = f(t<subscript>k</subscript>, yc(t<subscript>k-</subscript>), yd(t<subscript>k-1</subscript>), 1)
            </literal>
        </para>
        <para>
            (<literal>yc</literal> is time-continuous:
            <literal>yc(t<subscript>k-</subscript>) = yc(t<subscript>k</subscript>)</literal>).
        </para>
        <para>
            The calling parameters of <literal>f</literal> are fixed:
            <literal>ycd = f(t,yc,yd,flag)</literal>; this function must return either
            the derivative of the vector <literal>yc</literal> if
            <literal>flag=0</literal> or the update of <literal>yd</literal> if
            <literal>flag=1</literal>.
        </para>
        <para>
            <literal>ycd = dot(yc)</literal> must be a vector with same dimension
            as <literal>yc</literal> if <literal>flag=0</literal> and
            <literal>ycd = update(yd)</literal> must be a vector with same dimension as
            <literal>yd</literal> if <literal>flag=1</literal>.
        </para>
        <para>
            <literal>t</literal> is a vector of instants where the solution
            <literal>y</literal> is computed.
        </para>
        <para>
            <literal>y</literal> is the vector
            <literal>y = [y(t(1)), y(t(2)),...]</literal>.
        </para>
        <para>
            This function can be called with the same optional parameters as the <literal>ode</literal>
            function (provided <literal>nd</literal> and <literal>stdel</literal> are given in
            the syntax as second and third parameters). In particular
            integration flags, tolerances can be set. Optional parameters can be set
            by the <literal>odeoptions</literal> function.
        </para>
        <para>External routines can be dynamically linked (see <link linkend="link">link</link>).
        </para>
    </refsection>
    <refsection role="examples">
        <title>Examples</title>
        <programlisting role="example"><![CDATA[
//Linear system with switching input
deff('xdu = phis(t,x,u,flag)', 'if flag==0 then xdu=A*x+B*u; else xdu=1-u; end');
x0 = [1;1];
A = [-1,2;-2,-1];
B = [1;2];
u = 0;
nu = 1;
stdel = [1,0];
u0 = 0;
t = 0:0.05:10;
xu = odedc([x0;u0], nu, stdel, 0, t, phis);
x = xu(1:2,:);
u = xu(3,:);
nx = 2;
plot2d(t, x', [1:nx], '161')
plot2d2('onn', t', u', [nx+1:nx+nu], '000');
//Fortran external (see fydot2.f):
norm(xu - odedc([x0;u0], nu, stdel, 0, t, 'phis'), 1)
 ]]></programlisting>
        <scilab:image>
            deff('xdu=phis(t,x,u,flag)','if flag==0 then xdu=A*x+B*u; else xdu=1-u;end');
            x0=[1;1];
            A=[-1,2;-2,-1];
            B=[1;2];
            u=0;
            nu=1;
            stdel=[1,0];
            u0=0;
            t=0:0.05:10;
            xu=odedc([x0;u0],nu,stdel,0,t,phis);
            x=xu(1:2,:);
            u=xu(3,:);
            nx=2;
            plot2d(t, x', [1:nx],'161')
            plot2d2('onn',t',u',[nx+1:nx+nu],'000');
            //Fortran external (see fydot2.f):
        </scilab:image>
        <programlisting role="example"><![CDATA[

//Sampled feedback
//
//        |     xcdot=fc(t,xc,u)
//  (system)   |
//        |     y=hc(t,xc)
//
//
//        |     xd+=fd(xd,y)
//  (feedback) |
//        |     u=hd(t,xd)
//
deff('xcd = f(t,xc,xd,iflag)',...
  ['if iflag==0 then '
   '  xcd=fc(t,xc,e(t)-hd(t,xd));'
   'else '
   '  xcd=fd(xd,hc(t,xc));'
   'end']);
A = [-10,2,3;4,-10,6;7,8,-10];
B = [1;1;1];
C = [1,1,1];
Ad = [1/2,1;0,1/20];
Bd = [1;1];
Cd = [1,1];
deff('st = e(t)', 'st = sin(3*t)')
deff('xdot = fc(t,x,u)', 'xdot = A*x+B*u')
deff('y = hc(t,x)', 'y = C*x')
deff('xp = fd(x,y)', 'xp = Ad*x + Bd*y')
deff('u = hd(t,x)', 'u = Cd*x')
h = 0.1; t0=0; t=0:0.1:2;
x0c = [0;0;0];
x0d = [0;0];
nd = 2;
xcd = odedc([x0c;x0d], nd, h, t0, t, f);
norm(xcd - odedc([x0c;x0d], nd, h, t0, t, 'fcd1')) // Fast calculation (see fydot2.f)
plot2d([t',t',t'], xcd(1:3,:)');
scf(2);
plot2d2("gnn", [t',t'], xcd(4:5,:)');
scf(0);
 ]]></programlisting>
        <scilab:image>
            deff('xcd=f(t,xc,xd,iflag)',...
            ['if iflag==0 then '
            '  xcd=fc(t,xc,e(t)-hd(t,xd));'
            'else '
            '  xcd=fd(xd,hc(t,xc));'
            'end']);
            A=[-10,2,3;4,-10,6;7,8,-10];
            B=[1;1;1];
            C=[1,1,1];
            Ad=[1/2,1;0,1/20];
            Bd=[1;1];
            Cd=[1,1];
            deff('st=e(t)','st=sin(3*t)')
            deff('xdot=fc(t,x,u)','xdot=A*x+B*u')
            deff('y=hc(t,x)','y=C*x')
            deff('xp=fd(x,y)','xp=Ad*x + Bd*y')
            deff('u=hd(t,x)','u=Cd*x')
            h=0.1;t0=0;t=0:0.1:2;
            x0c=[0;0;0];
            x0d=[0;0];
            nd=2;
            xcd=odedc([x0c;x0d],nd,h,t0,t,f);
            plot2d([t',t',t'],xcd(1:3,:)');
        </scilab:image>
        <scilab:image>
            deff('xcd=f(t,xc,xd,iflag)',...
            ['if iflag==0 then '
            '  xcd=fc(t,xc,e(t)-hd(t,xd));'
            'else '
            '  xcd=fd(xd,hc(t,xc));'
            'end']);
            A=[-10,2,3;4,-10,6;7,8,-10];
            B=[1;1;1];
            C=[1,1,1];
            Ad=[1/2,1;0,1/20];
            Bd=[1;1];
            Cd=[1,1];
            deff('st=e(t)','st=sin(3*t)')
            deff('xdot=fc(t,x,u)','xdot=A*x+B*u')
            deff('y=hc(t,x)','y=C*x')
            deff('xp=fd(x,y)','xp=Ad*x + Bd*y')
            deff('u=hd(t,x)','u=Cd*x')
            h=0.1;t0=0;t=0:0.1:2;
            x0c=[0;0;0];
            x0d=[0;0];
            nd=2;
            xcd=odedc([x0c;x0d],nd,h,t0,t,f);
            plot2d2("gnn",[t',t'],xcd(4:5,:)');
        </scilab:image>

    </refsection>
    <refsection role="see also">
        <title>See also</title>
        <simplelist type="inline">
            <member>
                <link linkend="ode">ode</link>
            </member>
            <member>
                <link linkend="link">link</link>
            </member>
            <member>
                <link linkend="odeoptions">odeoptions</link>
            </member>
            <member>
                <link linkend="csim">csim</link>
            </member>
            <member>
                <link linkend="external">external</link>
            </member>
        </simplelist>
    </refsection>
</refentry>
