odedc программа решения дискретно-непрерывных ОДУ

## Синтаксис

    yt = odedc(y0, nd, stdel, t0, t, f)

## Аргументы

y0

  вещественный вектор-столбец (начальные условия), `y0=[y0c;y0d]`, где `y0d` имеет `nd` элементов.

nd

  целое число, размер `y0d`

stdel

  вещественный вектор с одним или двумя элементами `stdel=[h, delta]` (с `delta=0` в качестве значения по умолчанию).

t0

  вещественный скаляр (начальное время).

t

  вещественный вектор-(строка), моменты времени, в которые вычислено `yt`.

f

  внешняя функция, то есть функция или символьная строка или список с последовательностью вызова: `yp = f(t,yc,yd,flag)`.

  a list

    Эта форма внешней функции используется для передачи параметров в функцию. Она должна быть в следующем виде:

        list(f, p1, p2,...)

    где синтаксис функции `f` теперь

        yp = f(t, yc, yd, flag, p1, p2,...)

    `f` по-прежнему возвращает значение функции в виде функции `(t, yc, yd, flag, p1, p2,...)`, а `p1, p2,...` являются параметрами функции.

  символьная строка

    она должна ссылаться на имя модуля C или fortran, в предположении, что <`f_name`> является указанным именем.

    - Последовательность вызова Fortran должна быть

      `<f_name>(iflag, nc, nd, t, y, ydp)`

      `double precision t, y(*), ydp(*)`

      `integer iflag, nc, nd`

    - C-синтаксис должен быть

      `void <f_name> (int *iflag, int *nc, int *nd, double *t, double *y, double *ydp)`

    Как в случае Fortran, так и в случае C входными аргументами являются:

    - `iflag` = `0` или `1`

    - `nc` = число непрерывных состояний `yc`

    - `nd` = число дискретных состояний `yd`

    - `t` = время

    - `y` = `[yc; yd; param]`. `param` может быть использован для получения дополнительных аргументов, которые были указаны при вызове `odedc` `(y = odedc([y0c; y0d], nd, stdel, t0, t, list('fexcd', param)))`

    - В качестве выходного аргумента `ydp`, процедура должна вычислять `ydp[0:nc-1] = d/dt ( yc(t) )` для `iflag=0` и `ydp[0:nd-1] = yd(t+)` для `iflag=1`.

## Описание

`y = odedc([y0c;y0d], nd, [h,delta], t0, t, f)` вычисляет решение смешанной дискретно-непрерывной системы. Состояние дискретной системы `ydk` вложено в кусочно-постоянную функцию времени `yd(t)` в виде: `yd(t) = ydk` для `t` в `[tk = h*(delta+k) , tk+1 = h*(delta+k+1) )`.

Теперь моделируемые уравнения имеют вид, для t в [ tk , tk+1 ):

    dyc/dt = f(t, yc(t), yd(t), 0)
    yc(t0) = y0c

и в моменты времени `tk` дискретная переменная `yd` обновляется как

`yd(tk+) = f(yc(tk-), yd(tk-), 1)`.

Заметьте, что, используя определение `yd(t)`, последнее уравнение даёт

`ydk = f(tk, yc(tk-), yd(tk-1), 1)`

(`yc` непрерывно во времени : `yc(tk-) = yc(tk)`).

Параметры вызова `f` фиксированы: `ycd = f(t,yc,yd,flag)`; эта функция должно возвращать либо производную вектора `yc`, если `flag=0`, либо обновлять `yd`, если `flag=1`.

`ycd = dot(yc)` должна быть вектором того же размера, что и `yc`, если `flag=0` и `ycd = update(yd)` должна быть вектором того же размера, что и `yd`, если `flag=1`.

`t` -- это вектор моментов времени, в которых вычисляется решение `y`.

`y` -- это вектор `y = [y(t(1)), y(t(2)),...]`.

Эта функция может быть вызвана с теми же самыми необязательными параметрами, что и функция `ode` (указанные `nd` и `stdel` даны в последовательности вызова как второй и третий параметры). В частности, могут быть установлены флаги интегрирования, допуски. Необязательные параметры могут быть установлены с помощью функции `odeoptions`.

Внешние процедуры могут быть динамически скомпонованы (см. link).

## Примеры

    //Линейная система с переключающимися входами
    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);

## Смотрите также

- ode
- odeoptions
- link
- csim
- external