odedc — discrete/continuous ode solver
yt=odedc(y0,nd,stdel,t0,t,f)
real column vector (initial conditions), y0=[y0c;y0d]
where y0d
has nd
components.
integer, dimension of y0d
real vector with one or two entries, stdel=[h, delta]
(with delta=0
as default value).
real scalar (initial time).
real (row) vector, instants where yt
is calculated .
external i.e. function or character string or list with calling sequence: yp=f(t,yc,yd,flag)
.
y=odedc([y0c;y0d],nd,[h,delta],t0,t,f)
computes the solution of a mixed discrete/continuous system.
The discrete system state yd_k
is embedded into a piecewise constant yd(t)
time function as follows:
yd(t)=yd_k for t in [t_k=delay+k*h,t_(k+1)=delay+(k+1)*h[ (with delay=h*delta).
The simulated equations are now:
dyc/dt=f(t,yc(t),yd(t),0), for t in [t_k,t_(k+1)[ yc(t0)=y0c
and at instants t_k
the discrete variable yd
is updated by:
yd(t_k+)=f(yc(t_k-),yd(t_k-),1)
Note that, using the definition of yd(t)
the last equation gives
yd_k = f (t_k,yc(t_k-),yd(t_(k-1)),1) (yc is time-continuous: yc(t_k-)=yc(tk))
The calling parameters of f
are fixed: ycd=f(t,yc,yd,flag)
;
this function must return either the derivative of the vector yc
if
flag=0
or the update of yd
if flag=1
.
ycd=dot(yc)
must be a vector with same dimension as yc
if flag=0
and ycd=update(yd)
must be a vector with same
dimension as yd
if flag=1
.
t
is a vector of instants where the solution y
is computed.
y
is the vector y=[y(t(1)),y(t(2)),...]
.
This function can be called with the same optional parameters as the
ode
function (provided nd
and stdel
are given
in the calling sequence as second and third parameters).
In particular integration flags, tolerances can be set. Optional
parameters can be set by the odeoptions
function.
An example for calling an external routine is given in directory
SCIDIR/default/fydot2.f
External routines can be dynamically linked (see link
).
//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; plot2d1('onn',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) //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,:)'); xset("window",2);plot2d2("gnn",[t',t'],xcd(4:5,:)'); xset("window",0);