summaryrefslogtreecommitdiff
path: root/modules/cacsd/macros/dtsi.sci
diff options
context:
space:
mode:
Diffstat (limited to 'modules/cacsd/macros/dtsi.sci')
-rwxr-xr-xmodules/cacsd/macros/dtsi.sci152
1 files changed, 152 insertions, 0 deletions
diff --git a/modules/cacsd/macros/dtsi.sci b/modules/cacsd/macros/dtsi.sci
new file mode 100755
index 000000000..fe7eb2d17
--- /dev/null
+++ b/modules/cacsd/macros/dtsi.sci
@@ -0,0 +1,152 @@
+// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+// Copyright (C) INRIA -
+//
+// This file must be used under the terms of the CeCILL.
+// This source file is licensed as described in the file COPYING, which
+// you should have received as part of this distribution. The terms
+// are also available at
+// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt
+
+
+function [ga,gs,gi]=dtsi(g,tol)
+ //[ga,gs,gi]=dtsi(g,[tol]) stable-antistable decomposition of g:
+ // g = ga + gs + gi (gi = g(oo))
+ // g can be given in state-space form or in transfer form.
+ // (see syslin)
+ // - ga antistable and strictly proper.
+ // - gs stable and strictly proprer.
+ // - gi = g(oo)
+ // tol optional parameter for detecting stables poles.
+ // Default value: 100*%eps
+ //!
+
+ [lhs,rhs]=argn(0),
+ if rhs <1 then
+ error(msprintf(gettext("%s: Wrong number of input arguments: At least %d expected.\n"),"dtsi",1))
+ end
+
+ if and(typeof(g)<>["rational","state-space"]) then
+ error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"dtsi",1))
+ end
+ if g.dt<>"c" then
+ error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"dtsi",1))
+ end
+ if rhs==1 then
+ tol=100*%eps,
+ else
+ if type(tol)<>1|size(tol,"*")<>1|~isreal(tol)|tol<=0 then
+ error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be a positive scalar.\n"),"dtsi",2))
+ end
+ end,
+
+ select typeof(g)
+ case "rational" then
+ //transfer
+ //----------------------------
+ num=g.num,den=g.den,var=varn(den),
+ [t1,t2]=size(num),
+ num1=0*ones(t1,t2),num2=num1,
+ den1=ones(t1,t2),den2=den1,
+ for i=1:t1,
+ for j=1:t2,
+ n=num(i,j),d=den(i,j),
+ dn=degree(n),dd=degree(d),
+ if dn>dd then
+ error(msprintf(gettext("%s: Wrong values for input argument #%d: proper elements expected.\n"),"dtsi",1))
+ end,
+ //alf and bet /alf*d1(unstable) and bet*d2(stable)=n.
+ if dd==0 then
+ num2(i,j)=n,
+ else
+ pol=roots(d),
+ k=1,no=1,
+ [a,l]=gsort(real(pol));
+ pol=pol(l);
+ while k<=dd,
+ if real(pol(k))<=tol then
+ k=dd+1,
+ else
+ k=k+1,no=no+1,
+ end,
+ end,
+ select no,
+ case 1 then num2(i,j)=n,den2(i,j)=d,
+ case dd+1 then num1(i,j)=n,den1(i,j)=d,
+ else
+ d1=poly(pol(1:no-1),var),d2=poly(pol(no:dd),var),
+ if dn==dd then
+ d1o=poly([coeff(d1),0],var,"c"),
+ dd=dd+1,no=no+1,
+ else
+ d1o=d1,
+ end
+ u=sylm(d1o,d2),cn=[coeff(n),0*ones(1,dd-dn-1)],
+ x=u\cn',
+ alf=poly(x(1:dd-no+1),var,"c"),
+ bet=poly(x(dd-no+2:dd),var,"c"),
+ num1(i,j)=bet,den1(i,j)=d1,
+ num2(i,j)=alf,den2(i,j)=d2,
+ end,
+ end,
+ end,
+ end,
+ ga=syslin("c",num1,den1),gi1=ginfini(ga)
+ gs=syslin("c",num2,den2),gi2=ginfini(gs)
+
+ ga=ga-gi1,gs=gs-gi2,gi=gi1+gi2,return,
+ case "state-space" then
+ //state space:
+ //---------------------------
+ [a,b,c,d]=abcd(g),gi=d,
+ [n1,n2,t]=size(g),
+ [a,u0]=balanc(a);b=u0\b;c=c*u0;
+ [u,n]=schur(a,"c"),
+ a=u'*a*u,
+ if n==t then
+ ga=0,
+ gs=g,
+ return,
+ end,
+ if n==0 then
+ gs=0,
+ ga=g,
+ return,
+ end,
+ // [ab,w,bs]=bdiag(a);
+ a1=a(1:n,1:n),a4=a(n+1:t,n+1:t),x=a(1:n,n+1:t),
+ z=sylv(a1,-a4,-x,"c"),
+ w=[eye(n,n),z;0*ones(t-n,n),eye(t-n,t-n)],
+ wi=[eye(n,n),-z;0*ones(t-n,n),eye(t-n,t-n)],
+ tr=u*w,tri=wi*u';
+ bb=tri*b,b1=bb(1:n,:),b2=bb(n+1:t,:),
+ cc=c*tr,c1=cc(:,1:n),c2=cc(:,n+1:t),
+ ga=syslin("c",a4,b2,c2),
+ gs=syslin("c",a1,b1,c1);
+ end;
+
+endfunction
+
+function D=ginfini(g)
+ //gi=ginfini(g) computes D = g(infinity) for the proper transfer matrix g
+ //!
+ g1=g(1);
+ if typeof(g)=="constant" then D=g,return,end,
+ if typeof(g)<>"rational" then
+ error(msprintf(gettext("%s: Wrong type for input argument #%d: transfer function expected.\n"),"dtsi/ginfini",1))
+ end
+ num=g.num,den=g.den,
+ [nn,mm]=size(num),D=0*ones(nn,mm),
+ for i=1:nn,
+ for j=1:mm,
+ n=num(i,j),d=den(i,j),
+ dn=degree(n),dd=degree(d),
+ if dn>dd then
+ error(msprintf(gettext("%s: Wrong values for input argument #%d: Proper transfer function expected.\n"),"dtsi/ginfini",1 )),
+ else
+ if dn==dd then
+ D(i,j)=coeff(n,dn)/coeff(d,dd)
+ end,
+ end
+ end
+ end
+endfunction