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 — dynamic linker
- csim — simulation (time response) of linear system
- external — объект Scilab'а, внешняя функция или подпрограмма
Report an issue | ||
<< ode_root | Дифференциальное счисление, интегрирование | odeoptions >> |