File: csim.sci

package info (click to toggle)
scilab 4.0-12
  • links: PTS
  • area: non-free
  • in suites: etch, etch-m68k
  • size: 100,640 kB
  • ctags: 57,333
  • sloc: ansic: 377,889; fortran: 242,862; xml: 179,819; tcl: 42,062; sh: 10,593; ml: 9,441; makefile: 4,377; cpp: 1,354; java: 621; csh: 260; yacc: 247; perl: 130; lex: 126; asm: 72; lisp: 30
file content (133 lines) | stat: -rw-r--r-- 3,608 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
function [y,x]=csim(u,dt,sl,x0,tol)
//Syntax:
//  [y [,x]]=csim(u,dt,sl,[x0]) 
// simulation of the controlled linear system sl.
// sl is assumed to be a continuous-time system.
// u is the control and x0 the initial state.
//
//u can be:
// - a function 
//    [inputs]=u(t)
// - a list
//    list(ut,parameter1,....,parametern) such that
//    inputs=ut(t,parameter1,....,parametern)
// - the character string 'impuls' for impulse response calculation
//    (here sl is assumed SISO without direct feedthrough and x0=0)
// - the character string 'step' for step response calculation 
//    (here sl is assumed SISO without direct feedthrough and x0=0)
//dt is a vector of instants with dt(1) = initial time
//                   that is:           x0=x
//                                          dt(1)
//
//y matrix such that:
//  y=[y       y  ...  y     ]
//      dt(1)   dt(2)   dt(n)
//x matrix such that:
//  x=[x       x  ...  x     ]
//      dt(1)   dt(2)   dt(n)
//
//See also:
// dsimul flts ltitr rtitr ode impl
//!
// Copyright INRIA
[lhs,rhs]=argn(0)
//
if rhs<3 then error(39),end

if type(sl)<>16 then error(56,1),end
flag=sl(1)
select flag(1)
  case 'lss' then ,
  case  'r'  then sl=tf2ss(sl)
  else  error(97,1),
end;
if sl(7)<>'c' then warning('csim: time domain is assumed continuous'),end
//
[a,b,c,d]=sl(2:5);
if type(d)==2&degree(d)>0 then d=coeff(d,0);warning('D set to constant');end
[ma,mb]=size(b);
//
imp=0;text='if t==0 then y=0, else y=1,end'
//
select type(u)
 case 10 then //
    if mb<>1 then error(95,1);end;
    if part(u,1)=='i' then
           imp=1;
           if norm(d,1)<>0 then
               warning('direct feedthrough (d) <> 0;set to zero');
               d=0*d;
           end;
    end;
    deff('[y]=u(t)',text);
 case 11,comp(u)
 case 13,
 case 1 then
   [mbu,ntu]=size(u);
   if mbu<>mb | ntu<>size(dt,'*') then error('wrong size of u'), end
 case 15 then
    uu=u(1),
    if type(uu)==11 then 
      comp(uu),
      u(1)=uu,
    end
 else error(44,2)
end;
//
if rhs==3 then x0=sl(6),end
if imp==1 then x0=0*x0,end
nt=size(dt,'*');x=0*ones(ma,nt)
[a,v]=balanc(a);
//apply transformation u without matrix inversion
[k,l]=find(v<>0) //get the permutation
//apply right transformation 
v=v(k,l);c=c(:,k)*v; 
//apply left transformation 
v=diag(1 ./diag(v));b=v*b(k,:);x0=v*x0(k)

[a,v,bs]=bdiag(a,1);b=v\b;c=c*v;x0=v\x0;
//
if type(u)==1 then
   ut=u;
   if min(size(ut))==1 then ut=matrix(ut,1,-1),end
   deff('[y]=u(t)',['ind=find(dt<=t);nn=ind($)'
		    'if (t==dt(nn)|nn==nt) then '
		    '   y=ut(:,nn)'
		    'else '
		    '   y=ut(:,nn)+(t-dt(nn))/(dt(nn+1)-dt(nn))*(ut(:,nn+1)-ut(:,nn))'
		    'end']);
   deff('[ydot]=%sim2(%tt,%y)','ydot=ak*%y+bk*u(%tt)');
elseif type(u)<>15 then
  deff('[ydot]=%sim2(%tt,%y)','ydot=ak*%y+bk*u(%tt)');
  ut=ones(mb,nt);for k=1:nt, ut(:,k)=u(dt(k)),end
else
  %sim2=u
  tx=' ';for l=2:size(u), tx=tx+',%'+string(l-1);end;
  deff('[ydot]=sk(%tt,%y,u'+tx+')','ydot=ak*%y+bk*u(%tt'+tx+')');
  %sim2(0)=sk;u=u(1)
  deff('[ut]=uu(t)',...
     ['['+part(tx,3:length(tx))+']=%sim2(3:'+string(size(%sim2))+')';
      'ut=ones(mb,nt);for k=1:nt, ut(:,k)=u(t(k)'+tx+'),end'])
ut=uu(dt);
end;
//simulation
k=1;
for n=bs',
  kk=k:k+n-1
  ak=a(kk,kk)
  bk=b(kk,:)
  nrmu=maxi([norm(bk*ut,1),norm(x0(kk))])
  if nrmu > 0 then
    if rhs<5 then
      atol=1.d-10*nrmu;rtol=atol/100
    else
      atol=tol(1);rtol=tol(2)
    end
    x(kk,:)=ode('adams',x0(kk),dt(1),dt,rtol,atol,%sim2)
    if imp==1 then x(kk,:)=ak*x(kk,:)+bk*ut,end
  end;
  k=k+n
end;
if imp==0 then y=c*x+d*ut,else y=c*x,end
if lhs==2 then x=v*x,end
endfunction