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, ndC-синтаксис должен быть
void <f_name> (int *iflag, int *nc, int *nd, double *t, double *y, double *ydp)
Как в случае Fortran, так и в случае C входными аргументами являются:
iflag=0или1nc= число непрерывных состоянийycnd= число дискретных состоянийydt= время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 >> |