<?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="ru">
    <refnamediv>
        <refname>odedc</refname>
        <refpurpose>программа решения дискретно-непрерывных  ОДУ</refpurpose>
    </refnamediv>
    <refsynopsisdiv>
        <title>Синтаксис</title>
        <synopsis>yt = odedc(y0, nd, stdel, t0, t, f)</synopsis>
    </refsynopsisdiv>
    <refsection role="parameters">
        <title>Аргументы</title>
        <variablelist>
            <varlistentry>
                <term>y0</term>
                <listitem>
                    <para>
                        вещественный вектор-столбец (начальные условия),
                        <literal>y0=[y0c;y0d]</literal>, где <literal>y0d</literal>
                        имеет <literal>nd</literal> элементов.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>nd</term>
                <listitem>
                    <para>
                        целое число, размер <literal>y0d</literal>
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>stdel</term>
                <listitem>
                    <para>
                        вещественный вектор с одним или двумя элементами
                        <literal>stdel=[h, delta]</literal> (с <literal>delta=0</literal>
                        в качестве значения по умолчанию).
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>t0</term>
                <listitem>
                    <para>вещественный скаляр (начальное время).</para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>t</term>
                <listitem>
                    <para>
                        вещественный вектор-(строка), моменты времени, в которые вычислено
                        <literal>yt</literal>.
                    </para>
                </listitem>
            </varlistentry>
            <varlistentry>
                <term>f</term>
                <listitem>
                    <para>
                        внешняя функция, то есть функция или символьная строка или список
                        с последовательностью вызова: <literal>yp = f(t,yc,yd,flag)</literal>.
                    </para>
                    <variablelist>
                        <varlistentry>
                            <term>a list</term>
                            <listitem>
                                <para>
                                    Эта форма внешней функции используется для передачи параметров в функцию.
                                    Она должна быть в следующем виде:
                                </para>
                                <screen><![CDATA[
list(f, p1, p2,...)
]]></screen>
                                <para>
                                     где синтаксис функции <literal>f</literal> теперь
                                </para>
                                <screen><![CDATA[
yp = f(t, yc, yd, flag, p1, p2,...)
]]></screen>
                                <para>
                                    <literal>f</literal> по-прежнему возвращает значение функции в
                                    виде функции <literal>(t, yc, yd, flag, p1, p2,...)</literal>,
                                    а <literal>p1, p2,...</literal> являются параметрами функции.
                                </para>
                            </listitem>
                        </varlistentry>
                        <varlistentry>
                            <term>символьная строка</term>
                            <listitem>
                                <para>
                                    она должна ссылаться на имя модуля C или fortran, в
                                    предположении, что &lt;<literal>f_name</literal>&gt; является указанным именем.
                                </para>
                                <itemizedlist>
                                    <listitem>
                                        <para>
                                            Последовательность вызова Fortran должна быть
                                        </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>C-синтаксис должен быть</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>Как в случае Fortran, так и в случае C входными аргументами являются:</para>
                                <itemizedlist>
                                    <listitem>
                                        <para>
                                            <literal>iflag</literal> = <literal>0</literal> или
                                            <literal>1</literal>
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <literal>nc</literal> = число непрерывных состояний
                                            <literal>yc</literal>
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <literal>nd</literal> = число дискретных состояний
                                            <literal>yd</literal>
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <literal>t</literal> = время
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            <literal>y</literal> = <literal>[yc; yd; param]</literal>.
                                            <literal>param</literal> может быть использован для получения дополнительных
                                            аргументов, которые были указаны при вызове <literal>odedc</literal>
                                            <literal>(y = odedc([y0c; y0d], nd, stdel, t0, t, list('fexcd', param)))</literal>
                                        </para>
                                    </listitem>
                                    <listitem>
                                        <para>
                                            В качестве выходного аргумента <literal>ydp</literal>, процедура должна вычислять
                                            <literal>ydp[0:nc-1] = d/dt ( yc(t) )</literal>
                                            для <literal>iflag=0</literal> и
                                            <literal>ydp[0:nd-1] = yd(t+)</literal>
                                            для <literal>iflag=1</literal>.
                                        </para>
                                    </listitem>
                                </itemizedlist>
                            </listitem>
                        </varlistentry>
                    </variablelist>
                </listitem>
            </varlistentry>
        </variablelist>
    </refsection>
    <refsection role="description">
        <title>Описание</title>
        <para>
            <literal>y = odedc([y0c;y0d], nd, [h,delta], t0, t, f)</literal> вычисляет решение
            смешанной дискретно-непрерывной системы.
            Состояние дискретной системы <literal>yd<subscript>k</subscript></literal>
            вложено в кусочно-постоянную функцию времени <literal>yd(t)</literal> в виде:
            <literal>yd(t) = yd<subscript>k</subscript></literal> для <literal>t</literal> в
            <literal>[t<subscript>k</subscript> = h*(delta+k) ,
            t<subscript>k+1</subscript> = h*(delta+k+1) )</literal>.
        </para>
        <para>Теперь моделируемые уравнения имеют вид,
            для t в [ 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>
            и в моменты времени <literal>t<subscript>k</subscript></literal> дискретная переменная
            <literal>yd</literal> обновляется как
        </para>
        <para>
            <literal>yd(t<subscript>k+</subscript>)
            = f(yc(t<subscript>k-</subscript>), yd(t<subscript>k-</subscript>), 1)</literal>.
        </para>
        <para>
            Заметьте, что, используя определение <literal>yd(t)</literal>, последнее уравнение даёт
        </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> непрерывно во времени :
            <literal>yc(t<subscript>k-</subscript>) = yc(t<subscript>k</subscript>)</literal>).
        </para>
        <para>
            Параметры вызова <literal>f</literal> фиксированы:
            <literal>ycd = f(t,yc,yd,flag)</literal>; эта функция должно возвращать либо производную
            вектора <literal>yc</literal>, если <literal>flag=0</literal>, либо обновлять
            <literal>yd</literal>, если <literal>flag=1</literal>.
        </para>
        <para>
            <literal>ycd = dot(yc)</literal> должна быть вектором того же размера, что и
            <literal>yc</literal>, если <literal>flag=0</literal> и <literal>ycd = update(yd)</literal>
            должна быть вектором того же размера, что и <literal>yd</literal>, если
            <literal>flag=1</literal>.
        </para>
        <para>
            <literal>t</literal> -- это вектор моментов времени, в которых вычисляется решение
            <literal>y</literal>.
        </para>
        <para>
            <literal>y</literal> -- это вектор <literal>y = [y(t(1)), y(t(2)),...]</literal>.
        </para>
        <para>
            Эта функция может быть вызвана с теми же самыми необязательными параметрами,
            что и функция <literal>ode</literal>
            (указанные <literal>nd</literal> и <literal>stdel</literal> даны в последовательности
            вызова как второй и третий параметры). В частности, могут быть установлены флаги
            интегрирования, допуски. Необязательные параметры могут быть установлены с помощью
            функции <literal>odeoptions</literal>.
        </para>
        <para>
            Внешние процедуры могут быть динамически скомпонованы
            (см. <link linkend="link">link</link>).
        </para>
    </refsection>
    <refsection role="examples">
        <title>Примеры</title>
        <programlisting role="example"><![CDATA[
//Линейная система с переключающимися входами
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 (см. fydot2.f):
norm(xu-odedc([x0;u0],nu,stdel,0,t,'phis'), 1)

//Дискретизированная обратная связь
//
//      |    xcdot=fc(t,xc,u)
//  (система)      |
//      |      y=hc(t,xc)
//
//
//      |     xd+=fd(xd,y)
//  (обр. связь)   |
//      |      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')) // Быстрое вычисление (см. fydot2.f)
plot2d([t',t',t'], xcd(1:3,:)');
scf(2);
plot2d2("gnn",[t',t'],xcd(4:5,:)');
scf(0);
     ]]></programlisting>
    </refsection>
    <refsection role="see also">
        <title>Смотрите также</title>
        <simplelist type="inline">
            <member>
                <link linkend="ode">ode</link>
            </member>
            <member>
                <link linkend="odeoptions">odeoptions</link>
            </member>
            <member>
                <link linkend="link">link</link>
            </member>
            <member>
                <link linkend="csim">csim</link>
            </member>
            <member>
                <link linkend="external">external</link>
            </member>
        </simplelist>
    </refsection>
</refentry>
