diff options
author | Shashank | 2017-05-29 12:40:26 +0530 |
---|---|---|
committer | Shashank | 2017-05-29 12:40:26 +0530 |
commit | 0345245e860375a32c9a437c4a9d9cae807134e9 (patch) | |
tree | ad51ecbfa7bcd3cc5f09834f1bb8c08feaa526a4 /modules/cacsd/macros | |
download | scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.tar.gz scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.tar.bz2 scilab_for_xcos_on_cloud-0345245e860375a32c9a437c4a9d9cae807134e9.zip |
CMSCOPE changed
Diffstat (limited to 'modules/cacsd/macros')
351 files changed, 14525 insertions, 0 deletions
diff --git a/modules/cacsd/macros/abcd.bin b/modules/cacsd/macros/abcd.bin Binary files differnew file mode 100755 index 000000000..43a5f380c --- /dev/null +++ b/modules/cacsd/macros/abcd.bin diff --git a/modules/cacsd/macros/abcd.sci b/modules/cacsd/macros/abcd.sci new file mode 100755 index 000000000..6e8d54f5b --- /dev/null +++ b/modules/cacsd/macros/abcd.sci @@ -0,0 +1,23 @@ +// 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 [A,B,C,D]=abcd(sl) + // Retrieves [A,B,C,D] matrices from linear system sl + + select typeof(sl) + case "state-space" then + [A,B,C,D]=sl(2:5) + return; + case "rational" then + w=tf2ss(sl); + [A,B,C,D]=w(2:5) + else + error(msprintf(_("%s: Wrong type for input argument: Linear dynamical system expected.\n"),"abcd")) + end +endfunction diff --git a/modules/cacsd/macros/abinv.bin b/modules/cacsd/macros/abinv.bin Binary files differnew file mode 100755 index 000000000..7a1deea79 --- /dev/null +++ b/modules/cacsd/macros/abinv.bin diff --git a/modules/cacsd/macros/abinv.sci b/modules/cacsd/macros/abinv.sci new file mode 100755 index 000000000..21279aba7 --- /dev/null +++ b/modules/cacsd/macros/abinv.sci @@ -0,0 +1,196 @@ +// 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 [X,dims,F,U,k,Z]=abinv(Sl,Alfa,Beta,flag) + //Output nulling subspace (maximal unobservable subspace) for + // Sl = linear system defined by [A,B,C,D]; + // The dimV first columns of X i.e V=X(:,1:dimV), spans this subspace + // which is also the unobservable subspace of (A+B*F,C+D*F); + // The dimR first columns of X spans R, the controllable part of V (dimR<=dimV). + // (dimR=0 for a left invertible system). + // The dimVg first columns of X spans Vg=maximal AB-stabilizable subspace. + // (dimR<=dimVg<=dimV). The modes of X2'*(A*BF)*X(:,1:dimVg) are either + // assignable or stable. + // For X=[V,X2] (X2=X(:,dimV+1:nx)) one has X2'*(A+B*F)*V=0 and (C+D*F)*V=0 + // The zeros (transmission zeros for minimal Sl) are given by : + // X0=X(:,dimR+1:dimV); spec(X0'*(A+B*F)*X0) i.e. dimV-dimR closed-loop fixed modes + // If optional real parameter Alfa is given as input, the dimR controllable + // modes of (A+BF) are set to Alfa. + // Generically, for strictly proper systems one has: + // Fat plants (ny<nu): dimV=dimR=nx-nu --> no zeros + // Tall plants (ny>nu): dimV=dimR=0 --> no zeros + // Square plants (ny=nu): dimV=nx-nu, dimR=0, --> dimV zeros + // For proper (D full rank) plants, generically: + // Square plants: dimV=nx, dimR=0, --> nx zeros + // Tall plants: dimV=dimR=0 --> no zeros + // Fat plants: dimV=dimR=nx --> no zeros + // Z is a column compression of Sl and k the normal rank of Sl. + // + //DDPS: + // Find u=Fx+Rd which reject Q*d and stabilizes the plant: + // + // xdot=Ax+Bu+Qd + // y=Cx+Du + // + // DDPS has a solution iff Im(Q) is included in Vg + Im(B). + // Let G=(X(:,dimVg+1:nx))'= left anihilator of Vg i.e. G*Vg=0; + // B2=G*B; Q2=G*Q; DDP solvable if B2(:,1:k)*R1 + Q2 =0 has a solution. + // R=[R1;*] is the solution (with F=output of abinv). + // Im(Q2) is in Im(B2) means row-compression of B2=>row-compression of Q2 + // Then C*[(sI-A-B*F)^(-1)+D]*(Q+B*R) =0 (<=>G*(Q+B*R)=0) + //F.D. + //function [X,dims,F,U,k,Z]=abinv(Sl,Alfa,Beta,flag) + [LHS,RHS]=argn(0); + if and(typeof(Sl)<>["state-space" "rational"]) then + error(msprintf(_("%s: Wrong type for input argument #%d: Linear dynamical system expected.\n"),"abinv",1)) + end + select argn(2) + case 1 then + Alfa=-1;Beta=-1; + flag="ge"; + case 2 then + Beta=Alfa; + if type(Beta)<>1 then + error(msprintf(_("%s: Wrong type for input argument #%d: Array of floating point numbers expected.\n"),.. + "abinv",2)) + end + flag="ge"; + case 3 then + if type(Alfa)<>1 then + error(msprintf(_("%s: Wrong type for input argument #%d: Array of floating point numbers expected.\n"),.. + "abinv",2)) + end + if type(Beta)<>1 then + error(msprintf(_("%s: Wrong type for input argument #%d: Array of floating point numbers expected.\n"),.. + "abinv",3)) + end + flag="ge"; + case 4 then + if and(flag<>["ge","st","pp"]) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),.. + "abinv",4,"''ge'',''st'',''pp''")); + end + end + timedomain=Sl.dt; + if timedomain==[] then + warning(msprintf(gettext("%s: Input argument %d is assumed continuous time.\n"),"abinv",1)); + timedomain="c"; + end + [A,B,C,D]=abcd(Sl); + [nx,nu]=size(B); + Vi=eye(A); + [X,dimV]=im_inv([A;C],[Vi,B;zeros(C*Vi),D]); + Vi1=X(:,1:dimV); + while %t, + [X,n1]=im_inv([A;C],[Vi1,B;zeros(C*Vi1),D]); + if dimV==n1 then break;end + dimV=n1;Vi1=X(:,1:n1); + end + + //V=X(:,1:dimV); // V subspace + // Fast return if V=[]; + if dimV==0 then + dimR=0;dimVg=0; + [U,k]=colcomp([B;D]); + [ns,nc,X]=st_ility(Sl); + F=stabil(Sl("A"),Sl("B"),Beta); + select flag + case "ge" then + dims=[0,0,0,nc,ns]; + case "st" then + dims=[0,0,nc,ns]; + case "pp" then + dims=[0,nc,ns]; + end + Z=syslin(timedomain,A+B*F,B*U,F,U); + return; + end + Anew=X'*A*X;Bnew=X'*B;Cnew=C*X; + // Determining dimR and dimVg + B1V=Bnew(1:dimV,:);B2V=Bnew(dimV+1:nx,:); + [U,k]=colcomp([B2V;D]); //U is nu x nu + Uker=U(:,1:nu-k);Urange=U(:,nu-k+1:nu); + slV=syslin(timedomain,Anew(1:dimV,1:dimV),B1V*Uker,[]); + [dimVg,dimR,Ur]=st_ility(slV); + X(:,1:dimV)=X(:,1:dimV)*Ur; + Anew=X'*A*X;Bnew=X'*B;Cnew=C*X; + //Bnew=Bnew*U; + // Cut appropriate subspace + dim=dimVg; //dim=dimVg //dim=dimR + select flag + case "ge" + dim=dimV + case "st" + dim=dimVg + case "pp" + dim=dimR + end + A11=Anew(1:dim,1:dim); + B1=Bnew(1:dim,:);B2=Bnew(dim+1:nx,:); + [U,k]=colcomp([B2;D]); //U is nu x nu + Uker=U(:,1:nu-k);Urange=U(:,nu-k+1:nu); + B1t=B1*Uker;B1bar=B1*Urange; + sl1=syslin(timedomain,A11,B1t,[]); // + [dimVg1,dimR1,Ur]=st_ility(sl1); + A21=Anew(dim+1:nx,1:dim); + A22=Anew(dim+1:$,dim+1:$); + C1=Cnew(:,1:dim); + B2bar=B2*Urange;Dbar=D*Urange; + // B2bar,Dbar have k columns , B1t has nu-k columns and dim rows + Z=[A21,B2bar;C1,Dbar]; //Z is (nx-dim)+ny x dim+k + [W,nn]=colcomp(Z); // ? (dim+k-nn)=dim <=> k=nn ? if not-->problem + W1=W(:,1:dim)*inv(W(1:dim,1:dim)); + F1bar=W1(dim+1:dim+k,:); + //[A21,B2bar;C1,Dbar]*[eye(dim,dim);F1bar]=zeros(nx-dim+ny,dim) + // + A11=A11+B1bar*F1bar; //add B1bar*F1bar is not necessary. + if B1t ~= [] then + voidB1t=%f; + if RHS==1 then + warning(msprintf(gettext("%s: Needs %s => Use default value %s=%d.\n"),"abinv","Alfa","Alfa",-1)) + Alfa=-1; + end + F1t_tmp=0*sl1("B")'; //nu-k rows, dimV columns + else + voidB1t=%t;F1t_tmp=[];dimR=0; + end + + if ~voidB1t then + if norm(B1t,1)<1.d-10 then + F1t_tmp=zeros(nu-k,dim);dimR=0; + end + end + + sl2=syslin(timedomain,A22,B2*Urange,0*(B2*Urange)'); + [ns2,nc2,U2,sl3]=st_ility(sl2); + if (nc2~=0)&(RHS==1|RHS==2) then + warning(msprintf(gettext("%s: Needs %s => Use default value %s=%d.\n"),"abinv","Beta","Beta",-1)); + end + F2=Urange*stabil(sl2("A"),sl2("B"),Beta); + + //final patch + Ftmp=[U*[F1t_tmp;F1bar],F2]*X'; + An=X'*(A+B*Ftmp)*X;Bn=X'*B*U; + [m,n]=size(F1t_tmp); + A11=An(1:n,1:n);B11=Bn(1:n,1:m); + F1t=stabil(A11,B11,Alfa); + + F=[U*[F1t;F1bar],F2]*X'; + X=X*sysdiag(eye(Ur),U2); + select flag + case "ge" + dims=[dimR,dimVg,dimV,dimV+nc2,dimV+ns2]; + case "st" + dims=[dimR,dimVg,dimVg+nc2,dimVg+ns2]; + case "pp" + dims=[dimR,dimR+nc2,dimR+ns2]; + end + + Z=syslin(timedomain,A+B*F,B*U,F,U); +endfunction diff --git a/modules/cacsd/macros/acf.bin b/modules/cacsd/macros/acf.bin Binary files differnew file mode 100755 index 000000000..c5dea9a14 --- /dev/null +++ b/modules/cacsd/macros/acf.bin diff --git a/modules/cacsd/macros/acf.sci b/modules/cacsd/macros/acf.sci new file mode 100755 index 000000000..f83892e55 --- /dev/null +++ b/modules/cacsd/macros/acf.sci @@ -0,0 +1,25 @@ +// 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 [ac,Mean]=acf(x,n,minim,maxim) + //function acp(x,n,[minim,maxim]) + // Autocorrelation for one-deimensional process + + [lhs,rhs]=argn(0) + if rhs <= 1 ; n=prod(size(x))/4;end + if rhs <= 2 ; minim=-1.0;end + if rhs <= 3 ; maxim= 1.0;end + [cov,Mean]=corr(x,n+1); + ac=cov'/cov(1); + plot2d3("onn",(0:n)',ac,[1],"011"," ",[0,minim,n,maxim]); + //stde=sqrt((1+2*ac(2:n+1)'*ac(2:n+1))*1/prod(size(x))) + stde=2*sqrt(1/prod(size(x))); + plot2d( [0,0,0;n,n,n],[0,stde,-stde;0,stde,-stde],[1,2,2],"000") + xtitle(gettext("Autocorrelation Function")); +endfunction diff --git a/modules/cacsd/macros/arhnk.bin b/modules/cacsd/macros/arhnk.bin Binary files differnew file mode 100755 index 000000000..c484d7acd --- /dev/null +++ b/modules/cacsd/macros/arhnk.bin diff --git a/modules/cacsd/macros/arhnk.sci b/modules/cacsd/macros/arhnk.sci new file mode 100755 index 000000000..06b099974 --- /dev/null +++ b/modules/cacsd/macros/arhnk.sci @@ -0,0 +1,70 @@ +// 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 [slm]=arhnk(a,ordre,tol) + + [lhs,rhs]=argn(0), + if lhs<>1 then error(41),end + if typeof(a)<>"state-space" then error(91,1),end; + if a.dt<>"c" then error(93,1),end + select rhs + case 2 then istol=0; + case 3 then istol=1; + end; + + [a,b,c,d,x0,dom]=a(2:7); + if(max(real(spec(a)))) > 0 then + error(msprintf(_("%s: Wrong values for input argument #%d: Stable system expected.\n"),"arhnk",1)); + end + domaine="c" + wc=lyap(a',-b*b',domaine) + wo=lyap(a,-c'*c,domaine) + if istol==0 then [t,nn]=equil1(wc,wo); + else [t,nn]=equil1(wc,wo,tol); + end; + n1=nn(1); + ti=inv(t);a=t*a*ti;b=t*b;c=c*ti + wc=t*wc*t';wo=ti'*wo*ti; + if ordre>n1 then + ordre=n1 + end; + if ordre==n1 then + a=a(1:n1,1:n1);b=b(1:n1,:);c=c(:,1:n1); + if lhs==1 then a=syslin("c",a,b,c,d,0*ones(n1,1)),end + return, + end; + sigma=wc(ordre+1,ordre+1) + + r=max(n1-ordre-1,1) + + n=n1 + sel=[1:ordre ordre+r+1:n];seleq=ordre+1:ordre+r + b2=b(seleq,:);c2=c(:,seleq); + u=-c(:,seleq)*pinv(b(seleq,:)') + a=a(sel,sel);b=b(sel,:);c=c(:,sel); + wo=wo(sel,sel);wc=wc(sel,sel); + + Gamma=wc*wo-sigma*sigma*eye() + a=Gamma\(sigma*sigma*a'+wo*a*wc-sigma*c'*u*b') + b1=Gamma\(wo*b+sigma*c'*u) + c=c*wc+sigma*u*b';b=b1; + d=-sigma*u+d + // + [n,n]=size(a) + [u,m]=schur(a,"c") + a=u'*a*u;b=u'*b;c=c*u; + if m<n then + t=sylv(a(1:m,1:m),-a(m+1:n,m+1:n),-a(1:m,m+1:n),"c") + a=a(1:m,1:m) + b=b(1:m,:)-t*b(m+1:n,:) + c=c(:,1:m) + end; + // + slm=syslin("c",a,b,c,d,0*ones(m,1)); +endfunction diff --git a/modules/cacsd/macros/arl2.bin b/modules/cacsd/macros/arl2.bin Binary files differnew file mode 100755 index 000000000..7b1cc2021 --- /dev/null +++ b/modules/cacsd/macros/arl2.bin diff --git a/modules/cacsd/macros/arl2.sci b/modules/cacsd/macros/arl2.sci new file mode 100755 index 000000000..947dcbd65 --- /dev/null +++ b/modules/cacsd/macros/arl2.sci @@ -0,0 +1,24 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) ENPC - JPC +// Copyright (C) INRIA - Serge Steer , Francois Delebecque +// +// 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 [den,num,err]=arl2(y,den0,n,imp,all) + [lhs,rhs]=argn(0); + // test the system type 'c' 'd' or dt + if rhs <= 4 then all="one";end + if rhs <= 3 then imp=0;end + if all=="all" then + [den,num,err]=arl2_ius(y,den0,n,imp,all); + else + [den,num,err]=arl2_ius(y,den0,n,imp); + end; + if lhs<=1 then + den=syslin("d",num,den); + end +endfunction diff --git a/modules/cacsd/macros/arma2p.bin b/modules/cacsd/macros/arma2p.bin Binary files differnew file mode 100755 index 000000000..0c7c6f442 --- /dev/null +++ b/modules/cacsd/macros/arma2p.bin diff --git a/modules/cacsd/macros/arma2p.sci b/modules/cacsd/macros/arma2p.sci new file mode 100755 index 000000000..88570a96e --- /dev/null +++ b/modules/cacsd/macros/arma2p.sci @@ -0,0 +1,26 @@ +// 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 [A,B,D]=arma2p(ar) + // Build three polynomial matrices + // from an ar representation + if ar(1)<>"ar" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: %s data structure expected.\n"),.. + "arma2p",1,"armax")); + end; + A=inv_coeff(ar(2)); + if ar(3)<>[] then + [mb,nb]=size(ar(3)); + B=inv_coeff(ar(3),(nb/ar("nu"))-1); + else + B=[]; + end + D=inv_coeff(ar(4)); +endfunction diff --git a/modules/cacsd/macros/arma2ss.bin b/modules/cacsd/macros/arma2ss.bin Binary files differnew file mode 100755 index 000000000..b36fd65ab --- /dev/null +++ b/modules/cacsd/macros/arma2ss.bin diff --git a/modules/cacsd/macros/arma2ss.sci b/modules/cacsd/macros/arma2ss.sci new file mode 100755 index 000000000..340035430 --- /dev/null +++ b/modules/cacsd/macros/arma2ss.sci @@ -0,0 +1,69 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2012 - INRIA - Serge Steer +// +// 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 [S,Sn]=arma2ss(Ar) + //Ar : an armax data structure + //S : a discrete state space data structure (syslin) the regular input to + // output transfer + //Sn : a discrete state space data structure (syslin) the noise input to + // output transfer + if typeof(Ar)<>"ar" then + error(msprintf(_("%s : Wrong type for input argument #%d: An armax system expected.\n"),"arma2ss",1)) + end + a=Ar.a; + b=Ar.b; + d=Ar.d; + nu=Ar.nu; + sig=Ar.sig; + [ma,na]=size(a); + nb=size(b,2); + nd=size(d,2); + + a1=a(:,ma+1:$) //a(:,1:ma) supposed to be the identity + if a1==[] then a1=zeros(ma,ma);na=2*ma;end + + //the input to output transfer + A=[-a1, b(:,nu+1:$)]; + N=size(A,2); + A=[A + eye(na-2*ma,N)]; + B=[b(:,1:nu); + zeros(na-2*ma,nu)] + + M=size(A,1) + if nb-nu>0 then + A=[A + zeros(nu,N) + zeros(N-M-nu,na-ma) eye(N-M-nu,nb-nu)] + B=[B + eye(nu,nu) + zeros(N-M-nu,nu)] + end + C=eye(ma,N) + S=syslin("d",A,B,C) + + //the noise to output transfer + A=[-a1, d(:,ma+1:$)]; + N=size(A,2); + A=[A + eye(na-2*ma,N)]; + M=size(A,1) + B=[d(:,1:ma) + zeros(na-2*ma,ma)] + if nd-ma>0 then + A=[A + zeros(ma,N) + zeros(N-M-ma,na-ma) eye(N-M-ma,nd-ma)] + B=[B + eye(ma,ma) + zeros(N-M-ma,ma)] + end + + C=eye(ma,N) + Sn=syslin("d",A,B*sig,C) +endfunction diff --git a/modules/cacsd/macros/armac.bin b/modules/cacsd/macros/armac.bin Binary files differnew file mode 100755 index 000000000..ff2559049 --- /dev/null +++ b/modules/cacsd/macros/armac.bin diff --git a/modules/cacsd/macros/armac.sci b/modules/cacsd/macros/armac.sci new file mode 100755 index 000000000..bf71e6a34 --- /dev/null +++ b/modules/cacsd/macros/armac.sci @@ -0,0 +1,47 @@ +// 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 [ar]=armac(a,b,d,ny,nu,sig) + // just build a tlist for storing armacx coefficients + // A(z^-1)y= B(z^-1)u + D(z^-1)sig*e(t) + // a=<Id,a1,..,a_r>; matrix (ny,r*ny) + // b=<b0,.....,b_s>; matrix (ny,(s+1)*nu) + // d=<Id,d1,..,d_p>; matrix (ny,p*ny); + // ny : dim of observation y + // nu : dim of control u + // sig : standard deviation (ny,ny); + // + //! + + [na,la]=size(a); + if na<>ny then + error(msprintf(gettext("%s: Wrong size for input argument #%d: row dimension must be equal to %d.\n"),.. + "armac",1, ny)); + + end + [nb,lb]=size(b); + if nb<>0 & nb<>ny then + error(msprintf(gettext("%s: Wrong size for input argument #%d: row dimension must be equal to %d.\n"),.. + "armac",2, ny)); + end; + if lb<>0 & nu<>0 then + if modulo(lb,nu)<>0 then + error(msprintf(gettext("%s: Wrong size of input argument #%d: Number of columns are incompatible with %s.\n"),.. + "armac",2,"nu")); + end; + end + [nd,ld]=size(d); + if nd<>ny then + error(msprintf(gettext("%s: Wrong size for input argument #%d: row dimension must be equal to %d.\n"),.. + "armac",3, ny)); + + end + ar=tlist(["ar","a","b","d","ny","nu","sig"],a,b,d,ny,nu,sig); +endfunction diff --git a/modules/cacsd/macros/armax.bin b/modules/cacsd/macros/armax.bin Binary files differnew file mode 100755 index 000000000..0c2118ed3 --- /dev/null +++ b/modules/cacsd/macros/armax.bin diff --git a/modules/cacsd/macros/armax.sci b/modules/cacsd/macros/armax.sci new file mode 100755 index 000000000..9412994d2 --- /dev/null +++ b/modules/cacsd/macros/armax.sci @@ -0,0 +1,129 @@ +// 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 [archap,la,lb,sig,resid]=armax(r,s,y,u,b0f,prf) + // [la, lb, sig, resid] = armax(r, s, y, u, [b0f, prf]) + // armax identification + // Compute the coefficients of a n-dimensional ARX + // A(z^-1)y= B(z^-1)u + sig*e(t) + // e(t) is a white noise of n-dimensional Id variance + // sig is a n by n matrix + // A(z)= 1+a1*z+...+a_r*z^r; ( r=0 => A(z)=1) + // B(z)= b0+b1*z+...+b_s z^s ( s=-1 => B(z)=0) + // Method: + // Cfre : Eykhoff (trends and progress in system identification) page 96 + // Introducing z(t)=[y(t-1),..,y(t-r),u(t),...,u(t-s)] and + // oeff = [-a1,..,-ar,b0,...,b_s], we obtain + // y(t)= coef* z(t) + sig*e(t) + // and the algorithm is finding coef which minimizes + // sum_{t=1}^N ( [y(t)- coef'z(t)]^2) + // + // Input: + // y: output process y(ny, n); ny: dimension, + // n: sample size + // u: input process u(nu, n); nu: dimension + // n: sample size + // r and s: auto-regression orders r >=0 and s >=-1 + // b0f is optional parameter. By default, b0f is 0 and it + // means that this parameter must be identified. If b0f is 1, then + // b0f is supposed to be zero and is not identified. + // prf is optional parameter for display control. + // if prf = 1, a display is done (the default value) + // Output: + // la is the list(a,a+eta,a-eta); eta: estimated standard deviation + // a=[Id,a1,a2,...,ar] where ai: ny-by-ny matrix + // lb is the list(b,b+etb,b-etb); etb: estimated standard deviation + // b=[b0,.....,b_s] where bi is nu-by-nu matrix + // sig is the estimated standard deviation of noise + // resid=[ sig*e(t0),....]; + // t0=max(max(r,s)+1,1)); + // + // Example: + // Enter the command [a,b,sig,resid]=armax(); + // to see an example in dimension 1. + // Auteur: J-Ph. Chancelier ENPC Cergrene + //! + // Copyright INRIA + [lhs,rhs]=argn(0) + if rhs==0,write(%io(2),"/ / y_t = 0.2*u_{t-1}+0.01*e(t)"); + write(%io(2)," rand(''normal''); u=rand(1,1000);"); + write(%io(2)," y=arsimul([1],[0,0.2],1,0.01,u);"); + write(%io(2)," [archap,a,b,sig,resid]=armax(0,1,y,u)"); + write(%io(2),"/ / we must find a=1,b=[0,0.2]''"); + rand("normal"),u=rand(1,1000); + y=arsimul([1],[0,0.2],1,0.01,u); + [archap,la,lb,sig,resid]=armax(0,1,y,u,1); + return + end + if rhs<=5,prf=1;end + if rhs<=4,b0f=0;end + [ny,n2]=size(y) + [nu,n2u]=size(u) + // Compute zz matrix as + // zz(:,j)=[ y(t-1),...,y(t-r),u(t),...,u(t-s)]', with t=t0-1+j + // zz can be computed from t = t0 + t0=max(max(r,s)+1,1); + if r==0;if s==-1;error(msprintf(gettext("%s: Wrong value for input arguments: If %s and %s nothing to identify.\n"),"armax","r==0","s==-1")) + end;end + z=[]; + if r>=1;for i=1:r,z=[z ; y(:,t0-i:(n2-(i)))];end;end + if s>=-1;for i=b0f:s,z=[z ; u(:,t0-i:(n2-(i)))];end;end + zz= z*z'; + zy= z*y(:,t0:n2)'; + // Rank test + [nzl,nzc]=size(zz); + k=rank(zz); + if k<>nzl then + warning(msprintf(gettext("%s: %s is numerically singular.\n"),"armax","z*z''")); + end; + pv=pinv(zz); + coef=(pv*zy)'; + // The residual noise + resid=y(:,t0:n2) - coef*z; + // The variance of the residual noise + sig2= resid*resid'/(n2-t0+1) + // The standard deviation + sig=sqrtm(sig2); + a=[eye(ny,ny),-coef(:,1:r*ny)]; + if b0f==0 then + b=coef(:,r*ny+1:(s+1)*nu+r*ny); + else + b=[0*ones(ny,nu),coef(:,r*ny+1:r*ny+s*nu)]; + end + // For the SISO systems, the estimated standard deviation is added. + // It is to be done for the MIMO + if ny == 1, + dve=sqrt(diag(sig*pv,0))'; + la=list(a,a+[0,dve(1:r)],a-[0,dve(1:r)]); + if b0f==0 then + lb=list(b,b+dve(r+1:r+s+1),b-dve(r+1:r+s+1)), + else + lb=list(b,b+[0,dve(r+1:r+s)],b-[0,dve(r+1:r+s)]); + end + else + la=a;lb=b; + end + // If prf = 1, the display is done + //si prf vaut 1 on donne un display + archap=armac(a,b,eye(ny,ny),ny,nu,sig); + + if prf==1; + if ny==1, + [nla,nca]=size(la(2)); + mprintf(gettext("%s: Standard deviation of the estimator %s:\n"),"armax","a"); + form_a="(5x,"+string(nca)+"(f7.5,1x))"; + write(%io(2),la(2)-a,form_a); + if nu<>0 then + mprintf(gettext("%s: Standard deviation of the estimator %s:\n"),"armax","b"); + [nlb,ncb]=size(lb(2)); + write(%io(2),lb(2)-b,"(5x,"+string(ncb)+"(f7.5,1x))"); + end + end + end +endfunction diff --git a/modules/cacsd/macros/armax1.bin b/modules/cacsd/macros/armax1.bin Binary files differnew file mode 100755 index 000000000..5b345049e --- /dev/null +++ b/modules/cacsd/macros/armax1.bin diff --git a/modules/cacsd/macros/armax1.sci b/modules/cacsd/macros/armax1.sci new file mode 100755 index 000000000..95eafcf74 --- /dev/null +++ b/modules/cacsd/macros/armax1.sci @@ -0,0 +1,124 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// Copyright (C) ENPC - J-Ph. Chancelier +// +// 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 [arc,resid]=armax1(r,s,q,y,u,b0f) + // [arc, resid] = armax1(r, s, q, y, u, [b0f]) + // + // Compute the coefficient of monodimensional ARMAX + // A(z^-1)y= B(z^-1)u + D(z^-1)sig*e(t) + // e(t) is a white noise of variance 1 + // A(z)= 1+a1*z+...+a_r*z^r; ( r=0 => A(z)=1) + // B(z)= b0+b1*z+...+b_s z^s ( s=-1 => B(z)=0) + // D(z)= 1+d1*z+...+d_q*z^q ( q=0 => D(z)=1) + // + // Intput: + // y: output process + // u: input process + // r, s and q: auto-regression orders r >= 0, s >= 1 and moving average q. + // b0f is a optional parameter. By default, b0f is 0 and it means that + // this parameter must be identified. If b0f is 1, then b0f is supposed + // to be zero and is not identified. + // + // Output: + // arc is the tlist with fields + // a is the vector [1,a1,...,a_r] + // b is the vector [b0, ..., b_s] + // d is the vector [1, d1, ..., d_q] + // sig is the estimated standard deviation + // resid = [sig*echap(1), ..., ] + // + // Method: + // Cfre : Eykhoff (trends and progress in system identification) page 91 + // Introducing + // z(t)=[y(t-1),..,y(t-r),u(t),...,u(t-s),e(t-1),...,e(t-q)] and + // coef= [-a1,..,-ar,b0,...,b_s,d1,...,d_q]', we obtain + // y(t)= coef'* z(t) + sig*e(t). + // We use the sequential version of the AR estimation where e(t-i) is + // replaced by its estimated (Method RLLS). + // If q=0, it is a sequential version of the least squares algorithm given + // in armax function + + [lhs,rhs]=argn(0) + if rhs<=5,b0f=0;end + if s==-1,b0f=0;end // Seems not natural, but makes things work + u=matrix(u,1,-1);y=matrix(y,1,-1); //make u and y row vectors + [n1,n2]=size(y) + if size(y,"*")<>size(u,"*") then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same numbers of elements expected.\n"),.. + "armax1",4,5)); + end + // + t0=max(max(r,s+1),1)+1; + if r<>0;XTM1=y((t0-1):-1:(t0-r));else XTM1=[];end + if s<>-1;UTM1=u(t0-b0f:-1:(t0-s));else UTM1=[];end + if q<>0;ETM1=0*ones(1,q);else ETM1=[];end + npar=r+s+1-b0f+q + CTM1=0*ones(npar,1); + ZTM1=[XTM1,UTM1,ETM1]'; + PTM1=10.0*eye(npar,npar); + + for t=t0+1:n2, + if r<>0;XT=[ y(t-1), XTM1(1:(r-1))];else XT=[];end + if s<>-1;UT=[ u(t-b0f), UTM1(1:(s-b0f))];else UT=[];end + eeTM1=y(t-1)- CTM1'*ZTM1; + if q<>0;ET=[ eeTM1, ETM1(1:(q-1))];else ET=[];end + ZT=[XT,UT,ET]'; + // + KT=PTM1*ZT*(1/(1+ ZT'*PTM1*ZT)) + CT=CTM1+KT*(y(t)-ZT'*CTM1) + PT=PTM1-KT*ZT'*PTM1 + XTM1=XT;UTM1=UT;CTM1=CT;ETM1=ET;ZTM1=ZT;PTM1=PT; + end + // The coefficient a, b and d are extracted + // + if r<>0;a=[1;-CT(1:r)]';else a=1;end + if s<>-1; + if b0f==1,b=[0;CT(r+1:(r+s+1-b0f))]';else + b=[CT(r+1:(r+s+1-b0f))]';end + if q<>0;d=[1;CT(r+s+2-b0f:(r+s+q+1-b0f))]';else d=[1];end + else + b=0; + if q<>0;d=[1;CT(r+s+1-b0f:(r+s+q-b0f))]';else d=[1];end + end + // Simulation to get the prediction error + // + [sig,resid]=epred(r,s,q,CTM1,y,u,b0f); + arc=armac(a,b,d,1,1,sig); + + + +endfunction + +function [sig,resid]=epred(r,s,q,coef,y,u,b0f) + //============================================= + // [sig,resid] = epred(r,s,q,coef,y,u,b0f) + // Used by armax1 function to compute the prediction error + // coef= [-a1,..,-ar,b0,...,b_s,d1,...,d_q]' + // or + // coef= [-a1,..,-ar,b1,...,b_s,d1,...,d_q]' si b0f=1 + //! + [n1,n2]=size(y); + t0=max(max(r,s+1),1)+1; + if r<>0;XTM1=y((t0-1):-1:(t0-r));else XTM1=[];end + if s<>-1;UTM1=u(t0-b0f:-1:(t0-s));else UTM1=[];end + if q<>0;ETM1=0*ones(1,q);else ETM1=[];end + npar=r+s+1-b0f+q + ZTM1=[XTM1,UTM1,ETM1]'; + resid=0*ones(1,n2); + for t=t0+1:n2, + if r<>0;XT=[ y(t-1), XTM1(1:(r-1))];else XT=[];end + if s<>-1;UT=[ u(t-b0f), UTM1(1:(s-b0f))];else UT=[];end + resid(t)=y(t-1)- coef'*ZTM1; + if q<>0;ET=[ resid(t), ETM1(1:(q-1))];else ET=[];end + ZT=[XT,UT,ET]'; + XTM1=XT;UTM1=UT;ETM1=ET;ZTM1=ZT; + end + sig=sqrt(sum(resid.*resid)/size(resid,"*")) +endfunction diff --git a/modules/cacsd/macros/arsimul.bin b/modules/cacsd/macros/arsimul.bin Binary files differnew file mode 100755 index 000000000..903ec4c6f --- /dev/null +++ b/modules/cacsd/macros/arsimul.bin diff --git a/modules/cacsd/macros/arsimul.sci b/modules/cacsd/macros/arsimul.sci new file mode 100755 index 000000000..c18f46fc1 --- /dev/null +++ b/modules/cacsd/macros/arsimul.sci @@ -0,0 +1,130 @@ +// 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 z=arsimul(x1,x2,x3,x4,x5,x6,x7,x8) + // function z=arsimul(a,b,d,sig,u,up,yp,ep) + + [lhs,rhs]=argn(0) + // switch to ar representation + if type(x1)<>15&type(x1)<>16 then + if rhs < 5, + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"arsimul",5,8)); + end; + ar=armac(x1,x2,x3,size(x1,"r"),size(x5,"r"),x4); + if rhs==5,z=arsimul(ar,x5);return;end + if rhs==6,z=arsimul(ar,x5,x6);return;end + if rhs==7,z=arsimul(ar,x5,x6,x7);return;end; + if rhs==8,z=arsimul(ar,x5,x6,x7,x8);return;end; + end + // Here the call is always arsimul(ar,....) + a=x1("a");b=x1("b");d=x1("d");sig=x1("sig"); + u=x2; + [bl,bc]=size(b);[al,ac]=size(a);[dl,dc]=size(d); + [mmu,Nu]=size(u); + if mmu<>x1("nu") then + error(msprintf(gettext("%s: Number of rows of %s are incompatible with %s object.\n"),"arsimul","u","arma")); + return; + end; + // X = [y_{n-1},y_{n-2},...y_{n-ka},u_{n-1},....,u_{n-kb},e_{n-1},....,e_{n-kd} + a1=a(:,al+1:$);al1=size(a1,"c"); + b1=b(:,mmu+1:$);bl1=size(b1,"c"); + d1=d(:,al+1:$);dl1=size(d1,"c"); + A=[-a1,b1,d1]; + // y_{n} = A*X + b(:,1:mmu)*u_{n}+d(:,1:al)*e_{n} + // in the system fff x=[y_n;X]; + if A==[] then + deff("[xkp1]=fff(k,x)",... + ["ukp1=u(:,k+1);dkp1=br(:,k+1);"; + "xkp1= b(:,1:mmu)*ukp1+d(:,1:al)*dkp1"]); + else + deff("[xkp1]=fff(k,x)",... + ["x=x(al+1:$);ukp1=u(:,k+1);dkp1=br(:,k+1);"; + "ykp1= A*x + b(:,1:mmu)*ukp1+d(:,1:al)*dkp1"; + "xkp1=[];" + "if al1>0; xkp1=[ykp1;x(1:al1-al)];end;"; + "if bl1>0; xkp1=[xkp1;ukp1;x(al1+1:al1+bl1-mmu)];end;"; + "if dl1>0; xkp1=[xkp1;dkp1;x(al1+bl1+1:al1+bl1+dl1-al)];end;"; + "xkp1=[ykp1;xkp1];" ]); + end + // Noise simulation. + br=sig*rand(al,Nu,"normal"); + //br=[-2,1,0.5] + // Initial condition + // the first call to fff will be fff(0,x) + // x must be set to + // [ y_{0},...y{-ak},u_{0},...u_{-bk},d_{0},...d_{-dk} + // where ak= al1/al -1; bk= bl1/mmu -1 ; dk = dl1/al-1 + // past conditions for up + //-------------------------- + if rhs <=2, + up=0*ones(bl1,1); + else + up=x3; + if bl1==0 then + if up<>[] then error(msprintf(gettext("%s: Wrong size for input argument #%d: An empty matrix expected.\n"),"arsimul",3)) + return ; + end; + else + up_s=size(up) + if up_s(1)<>mmu|up_s(2)<>(bl1/mmu) then + error(msprintf(gettext("%s: %s must be of dimension (%s, %s).\n"),"arsimul","up=[u(0),u(-1),..,]",string(mmu),string(bl1/mmu))); + return + end + up=matrix(up,bl1,1); + end + end + // past conditions for yp + //-------------------------- + if rhs <=3, + yp=0*ones(al1,1) + else + yp=x4; + if al1==0 then + if yp<>[] then error(msprintf(gettext("%s: Wrong size for input argument #%d: An empty matrix expected.\n"),"arsimul",4)) + return ; + end; + else + yp_s=size(yp); + if yp_s(1)<>al|yp_s(2)<>(al1/al) then + error(msprintf(gettext("%s: %s must be of dimension (%s, %s).\n"), "arsimul","yp=[y(0),y(-1),..,]",string(al), string(al1/al))); + return; + end + yp=matrix(yp,al1,1); + end + end + // past conditions for ep + //-------------------------- + if rhs <=4, + ep=0*ones(dl1,1); + else + ep=x5 + if dl1==0 then + if ep<>[] then error(msprintf(gettext("%s: Wrong size for input argument #%d: An empty matrix expected.\n"),"arsimul",5)) + return ; + end; + else + ep_s=size(ep); + if ep_s(1)<>al|ep_s(2)<>(dl1/al) then + error(msprintf(gettext("%s: %s must be of dimension (%s, %s).\n"), "arsimul","ep=[e(0),e(-1),..,]",string(al), string(dl1/al))); + return; + end + ep=matrix(ep,dl1,1); + end; + end; + xi=[yp;up;ep]; + // If A=[] it is a degenerate case which also work + // but xi must be set to a scalar value to provide proper + // result dimensions. + // + xi=[0*ones(al,1);xi]; + z=ode("discrete",xi,0,1:Nu,fff); + // Now z contains y_{1},.....y_{Nu}; + z=z(1:al,:) +endfunction diff --git a/modules/cacsd/macros/augment.bin b/modules/cacsd/macros/augment.bin Binary files differnew file mode 100755 index 000000000..ac1c5cdb4 --- /dev/null +++ b/modules/cacsd/macros/augment.bin diff --git a/modules/cacsd/macros/augment.sci b/modules/cacsd/macros/augment.sci new file mode 100755 index 000000000..5da2f79ae --- /dev/null +++ b/modules/cacsd/macros/augment.sci @@ -0,0 +1,299 @@ +// 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 [P,r]=augment(G,SRT,flag) + // Augmented plants P + // flag='output' (default) : + // + // [ I | -G] -->'S' + // [ 0 | I] -->'R' + // P = [ 0 | G] -->'T' + // [-------] + // [ I | -G] + // + // + // flag='input' : + // + // [ I | -I] -->'S' + // [ G | -G] -->'R' + // P = [ 0 | I] -->'T' + // [-------] + // [ G | -G] + //! + + [LHS,RHS]=argn(0); + if RHS <= 2 then flag="output";end + select part(flag,1) + case "o" + G1=G(1); + if RHS==1 then SRT="SRT";end + r=size(G); + [ny,nu]=size(G);Iu=eye(nu,nu);Iy=eye(ny,ny); + Ouy=zeros(nu,ny);Oyu=zeros(ny,nu);Ouu=zeros(nu,nu); + Oyy=zeros(ny,ny); + ssSRT=0; + if G1(1)=="r" then ssSRT=1;end + long=length(SRT); + select long + case 3 then + // 'SRT' + if SRT<>"SRT" then + error(msprintf(gettext("%s: Wrong value for input argument #%d: ''%s'' expected.\n"), "augment",2,"SRT"),9999); + end + if ssSRT==0 then + W1=[Iy,Oyu,Oyy; + Ouy,Iu,Ouy; + -Iy,Oyu,Iy; + Iy,Oyu,Oyy]; + W2=[Iy,-G; + Ouy,Iu; + Iy,Oyu]; + P=W1*W2; + end + if ssSRT ==1 then + P=[Iy,-G; + Ouy,Iu; + Oyy,G; + Iy,-G] + end + return + case 2 then + if SRT=="SR" then + if ssSRT==0 then + W1=[Iy,Oyu,Oyy; + Ouy,Iu,Ouy; + Iy,Oyu,Oyy]; + W2=[Iy,-G; + Ouy,Iu; + Iy,Oyu]; + P=W1*W2; + end + if ssSRT==1 then + P=[Iy,-G; + Ouy,Iu; + Iy,-G]; + end + return + end + if SRT=="ST" then + if ssSRT==0 then + W1=[Iy,Oyu,Oyy; + -Iy,Oyu,Iy; + Iy,Oyu,Oyy]; + W2=[Iy,-G; + Ouy,Iu; + Iy,Oyu]; + P=W1*W2; + end + if ssSRT ==1 then + P=[Iy, -G; + Oyy, G; + Iy, -G]; + end + return + end + if SRT=="RT" then + if ssSRT==0 then + W1=[Ouy,Iu,Ouy; + -Iy,Oyu,Iy; + Iy,Oyu,Oyy]; + W2=[Iy,-G; + Ouy,Iu; + Iy,Oyu]; + P=W1*W2; + end; + if ssSRT ==1 then + P=[Ouy,Iu; + Oyy,G; + Iy,-G]; + end + return + end + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),.. + "augment",2, "''SR'',''ST'',''RT''"),9999); + case 1 then + if SRT=="S" then + if ssSRT==0 then + W1=[Iy,Oyu,Oyy; + Iy,Oyu,Oyy]; + W2=[Iy,-G; + Ouy,Iu; + Iy,Oyu]; + P=W1*W2; + end; + if ssSRT ==1 then + P=[Iy,-G; + Iy,-G]; + end + return + end + if SRT=="R" then + if ssSRT==0 then + W1=[Ouy,Iu,Ouy; + Iy,Oyu,Oyy]; + W2=[Iy,-G; + Ouy,Iu; + Iy,Oyu]; + P=W1*W2; + end + if ssSRT ==1 then + P=[Ouy,Iu; + Iy,-G]; + end + return + end + if SRT=="T" then + if ssSRT==0 then + W1=[-Iy,Oyu,Iy; + Iy,Oyu,Oyy]; + W2=[Iy,-G; + Ouy,Iu; + Iy,Oyu]; + P=W1*W2; + end + if ssSRT ==1 then + P=[Oyy,G; + Iy,-G]; + end + return + end + end + case "i" + G1=G(1); + if RHS==1 then SRT="SRT";end + r=size(G); + [ny,nu]=size(G);Iu=eye(nu,nu);Iy=eye(ny,ny); + Ouy=zeros(nu,ny);Oyu=zeros(ny,nu);Ouu=zeros(nu,nu); + Oyy=zeros(ny,ny); + ssSRT=0; + if G1(1)=="r" then ssSRT=1;end + long=length(SRT); + select long + case 3 then + // 'SRT' + if SRT<>"SRT" then + error(msprintf(gettext("%s: Wrong value for input argument #%d: ''%s'' expected.\n"), "augment",2,"SRT"),9999); + end; + if ssSRT==0 then + W1=[Iu,-Iu; + Oyu,Oyu; + Ouu,Iu; + Oyu,Oyu]; + W2=[Ouy;Iy;Ouy;Iy]; + W3=[Iu,-Iu]; + P=W1+W2*G*W3; + end + if ssSRT ==1 then + P=[Iu,-Iu; + G,-G; + Ouu,Iu; + -G,G] + end + return + case 2 then + if SRT=="SR" then + if ssSRT==0 then + W1=[Iu,-Iu; + Oyu,Oyu; + Oyu,Oyu]; + W2=[Ouy;Iy;Iy]; + W3=[Iu,-Iu]; + P=W1+W2*G*W3; + end + if ssSRT==1 then + P=[Iu,-Iu; + G,-G; + -G,G] + end + return + end + if SRT=="ST" then + if ssSRT==0 then + W1=[Iu,-Iu; + Ouu,Iu; + Oyu,Oyu]; + W2=[Ouy;Ouy;Iy]; + W3=[Iu,-Iu]; + P=W1+W2*G*W3; + end + if ssSRT ==1 then + P=[Iu,-Iu; + Ouu,Iu; + -G,G] + end + return + end + if SRT=="RT" then + if ssSRT==0 then + W1=[Oyu,Oyu; + Ouu,Iu; + Oyu,Oyu]; + W2=[Iy;Ouy;Iy]; + W3=[Iu,-Iu]; + P=W1+W2*G*W3; + end; + if ssSRT ==1 then + P=[G,-G; + Ouu,Iu; + -G,G] + end + return + end + + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),.. + "augment",2, "''SR'',''ST'',''RT''"),9999); + + case 1 then + if SRT=="S" then + if ssSRT==0 then + W1=[Iu,-Iu; + Oyu,Oyu]; + W2=[Ouy;Iy]; + W3=[Iu,-Iu]; + P=W1+W2*G*W3; + + end; + if ssSRT ==1 then + P=[Iu,-Iu; + -G,G] + end + return + end + if SRT=="R" then + if ssSRT==0 then + W1=[Oyu,Oyu; + Oyu,Oyu]; + W2=[Iy;Iy]; + W3=[Iu,-Iu]; + P=W1+W2*G*W3; + end + if ssSRT ==1 then + P=[G,-G; + -G,G] + end + return + end + if SRT=="T" then + if ssSRT==0 then + W1=[Ouu,Iu; + Oyu,Oyu]; + W2=[Ouy;Iy]; + W3=[Iu,-Iu]; + P=W1+W2*G*W3; + end + if ssSRT ==1 then + P=[Ouu,Iu; + -G,G] + end + return + end + end + end +endfunction diff --git a/modules/cacsd/macros/balreal.bin b/modules/cacsd/macros/balreal.bin Binary files differnew file mode 100755 index 000000000..fb43c1e7a --- /dev/null +++ b/modules/cacsd/macros/balreal.bin diff --git a/modules/cacsd/macros/balreal.sci b/modules/cacsd/macros/balreal.sci new file mode 100755 index 000000000..974db5404 --- /dev/null +++ b/modules/cacsd/macros/balreal.sci @@ -0,0 +1,32 @@ +// 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 [slb,u]=balreal(a) + + [lhs,rhs]=argn(0) + + if typeof(a)<>"state-space" then error(91,1),end + [a,b,c,d,x0,dom]=a(2:7); + if dom==[] then error(96,1),end + domain="c"; + if dom<>"c" then domain="d",end + wc=lyap(a',-b*b',domain) + wo=lyap(a,-c'*c,domain) + r=chol(wo);x=r*wc*r';[u,s,v]=svd(x);s=diag(s); + ns=size(s,"*"); + lli=sqrt(sqrt(s));ll=ones(ns,1)./lli + ri=inv(r)*v;r=v'*r; + a=r*a*ri;b=r*b;c=c*ri + a=diag(ll)*a*diag(lli) + b=diag(ll)*b + c=c*diag(lli) + slb=syslin(dom,a,b,c,d,diag(ll)*r*x0), + if lhs==2 then u=ri*diag(lli),end +endfunction diff --git a/modules/cacsd/macros/bilin.bin b/modules/cacsd/macros/bilin.bin Binary files differnew file mode 100755 index 000000000..07a82eea5 --- /dev/null +++ b/modules/cacsd/macros/bilin.bin diff --git a/modules/cacsd/macros/bilin.sci b/modules/cacsd/macros/bilin.sci new file mode 100755 index 000000000..60a850361 --- /dev/null +++ b/modules/cacsd/macros/bilin.sci @@ -0,0 +1,26 @@ +// 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 Sl2=bilin(Sl1,v) + + [A,B,C,D]=abcd(Sl1); + dom=Sl1("dt"); + [ra,ca] = size(A); + a=v(1);d=v(2);c=v(3);b=v(4); + i=inv(a*eye(ra,ra)-c*A); + AB=(b*A-d*eye(ra,ra))*i; + BB=(a*b-c*d)*i*B; + CB=C*i; + DB=D+c*C*i*B; + if dom=="c" then Sl2=syslin("d",AB,BB,CB,DB); + else Sl2=syslin("c",AB,BB,CB,DB);end + + +endfunction diff --git a/modules/cacsd/macros/black.bin b/modules/cacsd/macros/black.bin Binary files differnew file mode 100755 index 000000000..0aeacff7c --- /dev/null +++ b/modules/cacsd/macros/black.bin diff --git a/modules/cacsd/macros/black.sci b/modules/cacsd/macros/black.sci new file mode 100755 index 000000000..cc4ad0a87 --- /dev/null +++ b/modules/cacsd/macros/black.sci @@ -0,0 +1,222 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 1998-2010 - INRIA - Serge Steer +// Copyright (C) 2010 - DIGITEO - Yann COLLETTE +// 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 black(varargin) + //Black's diagram (Nichols chart) for a linear system sl. + //sl can be a continuous-time, discrete-time or sampled SIMO system + //Syntax: + // + // black( sl,fmin,fmax [,pas] [,comments] ) + // black(frq,db,phi [,comments]) + // black(frq, repf [,comments]) + // + // sl : SIMO linear system (see syslin). In case of multi-output + // system the outputs are plotted with differents symbols. + // + // fmin : minimal frequency (in Hz). + // fmax : maximal frequency (in Hz). + // pas : logarithmic discretization step. (see calfrq for the + // choice of default value). + // comments : character strings to comment the curves. + // + // frq : (row)-vector of frequencies (in Hz) or (SIMO case) matrix + // of frequencies. + // db : matrix of modulus (in Db). One row for each response. + // phi : matrix of phases (in degrees). One row for each response. + // repf : matrix of complex numbers. One row for each response. + + //To plot the grid of iso-gain and iso-phase of y/(1+y) use abaque() + //%Example + // s=poly(0,"s") + // h=syslin("c",(s**2+2*0.9*10*s+100)/(s**2+2*0.3*10.1*s+102.01)) + // nicholschart(); + // black(h,0.01,100,"(s**2+2*0.9*10*s+100)/(s**2+2*0.3*10.1*s+102.01)") + // // + // h1=h*syslin("c",(s**2+2*0.1*15.1*s+228.01)/(s**2+2*0.9*15*s+225)) + // black([h1;h],0.01,100,["h1";"h"]) + //See also: + // bode nyquist nicholschart freq repfreq + //! + rhs=size(varargin) + if type(varargin($))==10 then + comments=varargin($),rhs=rhs-1; + else + comments=[]; + end + fname="black";//for error messages + fmax=[] + if or(typeof(varargin(1))==["state-space" "rational"]) then + //sys,fmin,fmax [,pas] or sys,frq + refdim=1 //for error message + if rhs==1 then + [frq,repf]=repfreq(varargin(1),1d-3,1d3) + elseif rhs==2 then //sys,frq + if size(varargin(2),2)<2 then + error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"),.. + fname,2,1)) + end + [frq,repf]=repfreq(varargin(1:rhs)) + elseif or(rhs==(3:4)) then //sys,fmin,fmax [,pas] + [frq,repf]=repfreq(varargin(1:rhs)) + else + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),fname,1,5)) + end + [phi,d]=phasemag(repf) + if rhs>=3 then fmax=varargin(3),end + elseif type(varargin(1))==1 then + //frq,db,phi [,comments] or frq, repf [,comments] + refdim=2 + select rhs + case 2 then //frq,repf + frq=varargin(1); + if size(frq,2)<2 then + error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"),.. + fname,1,1)) + end + if size(frq,2)<>size(varargin(2),2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),.. + fname,1,2)) + end + [phi,d]=phasemag(varargin(2)) + case 3 then //frq,db,phi + [frq,d,phi]=varargin(1:rhs) + if size(frq,2)<>size(d,2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),.. + fname,1,2)) + end + if size(frq,2)<>size(phi,2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),.. + fname,1,3)) + end + else + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),fname,2,4)) + end + else + error(msprintf(_("%s: Wrong type for input argument #%d: Linear dynamical system or row vector of floats expected.\n"),fname,1)) + end; + + if size(frq,1)==1 then + ilf=0 + else + ilf=1 + end + + [mn,n]=size(phi); + if and(size(comments,"*")<>[0 mn]) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same number of elements expected.\n"),... + fname,refdim,rhs+1)) + end + + // + xmn=floor(min(phi)/90)*90 + xmx=ceil(max(phi)/90)*90 + ymn=min(d) + ymx=max(d) + + + kf=1 + phi1=phi+5*ones(phi); + + kk=1;p0=[phi(:,kk) d(:,kk)];ks=1;Dst=0; + dx=max(%eps,xmx-xmn); + dy=max(%eps,ymx-ymn); + dx2=dx.^2;dy2=dy.^2 + + while kk<n + kk=kk+1 + Dst=Dst+min(sqrt(((phi(:,kk-1)-phi(:,kk)).^2)/dx2+((d(:,kk-1)-d(:,kk)).^2)/dy2)) + if Dst>0.2 then + if min(abs(frq(:,ks(prod(size(ks))))-frq(:,kk))./frq(:,kk))>0.2 then + ks=[ks kk] + Dst=0 + end + end + end + kf=1 + fig=gcf(); + immediate_drawing=fig.immediate_drawing; + fig.immediate_drawing="off"; + + ax=gca(); + if size(ax.children,"*")==0 then + ax.data_bounds=[xmn ymn;xmx ymx]; + ax.x_label.text=_("Phase (deg)"); + ax.y_label.text=_("Magnitude (dB)") + else + ax.data_bounds=[min([xmn ymn],ax.data_bounds(1,:)); + max([xmx ymx],ax.data_bounds(2,:))]; + end + ax.axes_visible="on"; + ax.clip_state="clipgrf"; + r=xstringl(0,0,"m");r=r(3) + E=[] + if ks($)<size(phi,2) then last=$;else last=$-1;end + for k=1:mn + e2=[] + if size(ks,"*") >1 then + d_phi=phi(k,ks(1:last)+1)-phi(k,ks(1:last)); + d_d=d(k,ks(1:last)+1)-d(k,ks(1:last)); + dd=400*sqrt((d_phi/dx).^2+(d_d/dy).^2); + if dd>0 then + // we should use xarrows or xsegs here. + // However their displayed arrow size depends + // on the data bounds and we want to avoid this. + xpolys([phi(k,ks(1:last));phi(k,ks(1:last))+d_phi./dd],.. + [d(k,ks(1:last));d(k,ks(1:last))+d_d./dd]); + ea=gce(); + ea.children.foreground=k; + ea.children.polyline_style = 4; + ea.children.arrow_size_factor = 1.5; + + //xarrows([phi(k,ks(1:last));phi(k,ks(1:last))+d_phi./dd],.. + // [d(k,ks(1:last));d(k,ks(1:last))+d_d./dd],60) + //ea=gce();ea.segs_color=k*ones(dd); + //add a frequency label near each arrow + el=[]; + + for l=ks + xstring(phi(k,l)+r,d(k,l),msprintf("%-5.2g",frq(kf,l))) + e=gce() + e.font_foreground=k; + el=[e,el] + end + e2=glue([el ea]) + end + end + + xpoly(phi(k,:),d(k,:));e1=gce() + e1.foreground=k; + e1.display_function = "formatBlackTip"; + e1.display_function_data = frq(kf,:); + + // glue entities relative to a single black curve + E=[E glue([e2 e1])] + kf=kf+ilf + end + + + // 2.3 db curve + mbf=2.3; + lmda=exp(log(10)/20*mbf); + r=lmda/(lmda**2-1); + npts=100; + crcl=exp(%i*(-%pi:(2*%pi/npts):%pi)); + lgmt=log(-r*crcl+r*lmda*ones(crcl)); + xpoly([180*(imag(lgmt)/%pi-ones(lgmt))],[(20/log(10)*real(lgmt))]) + e=gce();e.foreground=2;e.line_style=3; + if comments<>[] then + c=[]; + for k=1:mn + c=[c, E(k).children(1)]; + end + legend([c e]',[comments(:); "2.3"+_("dB")]) + end + fig.immediate_drawing=immediate_drawing; +endfunction diff --git a/modules/cacsd/macros/bloc2exp.bin b/modules/cacsd/macros/bloc2exp.bin Binary files differnew file mode 100755 index 000000000..d16a9c5a1 --- /dev/null +++ b/modules/cacsd/macros/bloc2exp.bin diff --git a/modules/cacsd/macros/bloc2exp.sci b/modules/cacsd/macros/bloc2exp.sci new file mode 100755 index 000000000..aa55284e7 --- /dev/null +++ b/modules/cacsd/macros/bloc2exp.sci @@ -0,0 +1,165 @@ +// 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 [h,name]=bloc2exp(syst,sexp) + + [lhs,rhs]=argn(0) + + if type(syst)<>15 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A list expected.\n"),"bloc2exp",1)); + end; + if syst(1)<>"blocd" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A list expected.\n"),"bloc2exp",1)); + end; + //inter%connection matrix + nsyst=size(syst) + for l=2:nsyst + sys=syst(l) + if sys(1)=="blocd" then + if rhs==1 then sys=bloc2exp(sys) + syst(l)=list("transfer",sys) + else [sys]=bloc2exp(sys,sexp) + syst(l)=list("transfer",sys(1)) + sexp=sys(2) + end; + end; + end; + if lhs==2 then [t,nio,name]=construct(syst) + else [t,nio]=construct(syst) + end; + //linear equation + if rhs==1 then + t=trianfml(t) + else + [t,sexp]=trianfml(t,sexp) + end + [nt,mt]=size(t) + h=t(nt-nio(2)+1:nt,nt+1:mt) + for kt=1:nio(1),for lt=1:nio(2), + h(lt,kt)=mulf("-1",h(lt,kt)) + end,end, + if rhs==1 then h=trisolve(t(nt-nio(2)+1:nt,nt-nio(2)+1:nt),h) + else [h,sexp]=trisolve(t(nt-nio(2)+1:nt,nt-nio(2)+1:nt),h,sexp) + h=list(h,sexp) + end; + if lhs==2 then name=list(name(nt+1:mt)',name(nt-nio(2)+1:nt)'),end, + +endfunction +function [ab,nio,name]=construct(syst) + //! + [lhs,rhs]=argn(0) + + [lboites,lliens,lentrees,lsorties]=blocdext(syst) + nio=[prod(size(lentrees)),prod(size(lsorties))] + lliens=[lliens,lsorties] + nlignes=prod(size(lliens)) + ncols=nlignes+nio(1) + // + ab=string(0*ones(nlignes,ncols)) + l=1; + for numero=lboites + //on ecrit les equations relatives a la boite "bloc" --> une ligne bloc de la + //matrice ab + bloc=syst(numero) + transfert=bloc(2);[no,ni]=size(transfert); + l1=l+no-1; + outint=out1(numero,lliens) + internes=%connect(numero,lliens); + externes=%connect(numero,lentrees); + for inti=internes + ni=prod(size(inti)) + ab(l:l1,inti(1))=transfert(:,inti(2:ni)) + ll=0;for iout=outint + ab(l-1+iout(2),iout(1))="-eye()" + ll=ll+1 + end; + end; + for ext=externes + ne=prod(size(ext)) + ab(l:l1,nlignes+ext(1))=transfert(:,ext(2:ne)) + ll=0;for iout=outint + ab(l-1+iout(2),iout(1))="-eye()" + ll=ll+1 + end; + end; + l=l1+1 + end; + if lhs==1 then return,end + name=[] + for kvar=[lliens,lentrees], + obj=syst(kvar) + name=[name,obj(2)] + end; + +endfunction +function [lboites,lliens,lentrees,lsorties]=blocdext(syst) + //! + // + lboites=[] + lliens=[] + lentrees=[] + lsorties=[] + nsyst=size(syst) + for k=2:nsyst + obj=syst(k) + if type(obj)==15, if size(obj)>1 then + select obj(1) + case "transfer", + lboites=[lboites,k] + case "link" + obj2=obj(3) + if obj2(1)>0 then + nobj=size(obj) + is_sortie=[] + for ko=3:nobj + objk=obj(ko) + if objk(1)<0 then is_sortie=[is_sortie,-objk(1)],end + end; + if is_sortie==[] then lliens=[lliens,k], + else lsorties(1,is_sortie)=k + end; + else lentrees(1,-obj2(1))=k, + end; + else error(msprintf(gettext("%s: Undefined type ''%s''.\n"),"bloc2exp",obj(1))) + end; + end,end + end; + if min(lsorties)==0 then + error(msprintf(gettext("%s: Some output(s) are undefined.\n"),"bloc2exp")), + end + if min(lentrees)==0 then + error(msprintf(gettext("%s: Some input(s) are undefined.\n"),"bloc2exp")), + end + +endfunction +function [where_x]=%connect(bloc,lliens,syst) + where_x=list();nw=0 + nliens=prod(size(lliens)) + for l=1:nliens, + lien=syst(lliens(l)); + nb=size(lien); + whi=l + for k=4:nb, + output=lien(k), + if bloc==output(1) then whi=[whi,output(2)],end; + end; + if prod(size(whi))>1 then nw=nw+1,where_x(nw)=whi,end + end; + +endfunction +function [where_x]=out1(bloc,lliens,syst) + where_x=[];l=0; + for li=lliens + lien=syst(li) + nb=size(lien);l=l+1; + output=lien(3), + if bloc==output(1) then where_x=[where_x,[l;output(2)]],end; + end; +endfunction diff --git a/modules/cacsd/macros/bloc2ss.bin b/modules/cacsd/macros/bloc2ss.bin Binary files differnew file mode 100755 index 000000000..24300aa8b --- /dev/null +++ b/modules/cacsd/macros/bloc2ss.bin diff --git a/modules/cacsd/macros/bloc2ss.sci b/modules/cacsd/macros/bloc2ss.sci new file mode 100755 index 000000000..b9297be9c --- /dev/null +++ b/modules/cacsd/macros/bloc2ss.sci @@ -0,0 +1,241 @@ +// 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 [sl,name]=bloc2ss(syst) + // + + [lhs,rhs]=argn(0) + + if type(syst)<>15 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A list expected.\n"),"bloc2ss",1)) + end; + syst1=syst(1); + if syst1(1)<>"blocd" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A list expected.\n"),"bloc2ss",1)) + end; + + nsyst=size(syst) + dom=[] + for l=2:nsyst + sys=syst(l) + typ=part(sys(1),1) + if typ<>"l" then + if typ=="b" then + //recursion pour traiter les description bloc imbriquees + sys=list("transfert",bloc2ss(sys)) + syst(l)=sys + end + transfert=sys(2) + if type(transfert)==10 then transfert=evstr(transfert);end + tr1=transfert(1); + if tr1(1)=="r" then transfert=tf2ss(transfert);end + syst(l)=list("transfert",transfert) + + if type(transfert)==16 then + d=transfert(7) + if d<>[] then + if dom==[] then + dom=d + elseif dom<>d then + if dom=="c" then + error(msprintf(gettext("%s: Hybrid system not implemented.\n"),"bloc2ss")) + elseif dom=="d"&type(d)==1 then + dom=d + elseif type(dom)==1&type(d)==1 then + error(msprintf(gettext("%s: Multi rate discrete system not implemented.\n"),"bloc2ss")) + end + end + end + end + end; + end; + [lboites,lliens,lentrees,lsorties]=blocdext(syst) + nio=[prod(size(lentrees)),prod(size(lsorties))] + // + lliens=[lliens lentrees lsorties] + if lhs==2 then + in_names=[] + for kvar=lentrees + obj=syst(kvar) + in_names=[in_names;obj(2)] + end + out_names=[] + for kvar=lsorties + obj=syst(kvar) + out_names=[out_names;obj(2)] + end + name=list(in_names,out_names) + end + //on ecrit le systeme bloc diagonal constitue de l'ensemble des sous systemes + + a=[];ms=0;b=[];mi=0;c=[];mo=0;d=[];lgain=[] + insize=1;outsize=1;inn=1;outn=1; + in=[];out=[]; + corresp=[];l=0 + for numero=lboites + l=l+1 + corresp(numero)=l + bloc=syst(numero);transfert=bloc(2) + if type(transfert)==1 then //c'est un gain + [mok,mik]=size(transfert) + [msk,msk]=size([]) + if ms>0 then + b(ms,mi+1:mi+mik)=0*ones(1,mik) + c(mo+1:mo+mok,ms)=0*ones(mok,1) + end + d(mo+1:mo+mok,mi+1:mi+mik)=transfert + mo=mo+mok;mi=mi+mik;ms=ms+msk + insize=[insize insize(inn)+mik];inn=inn+1 + outsize=[outsize outsize(outn)+mok];outn=outn+1 + else // un bloc dynamique + [mok,mik]=size(transfert(5)) + [msk,msk]=size(transfert(2)) + a(ms+1:ms+msk,ms+1:ms+msk)=transfert(2) + b(ms+1:ms+msk,mi+1:mi+mik)=transfert(3) + c(mo+1:mo+mok,ms+1:ms+msk)=transfert(4) + d(mo+1:mo+mok,mi+1:mi+mik)=transfert(5) + mo=mo+mok;mi=mi+mik;ms=ms+msk + insize=[insize insize(inn)+mik];inn=inn+1 + outsize=[outsize outsize(outn)+mok];outn=outn+1 + end + end + //on ecrit la matrice de feedback K + k=0*ones(insize(inn)-1,outsize(outn)-1) + for numero=lliens + + fil=syst(numero) + + nnum=size(fil)-3 + if nnum<=0 then + error(msprintf(gettext("%s: Incorrect link: %s"),"bloc2ss",string(numero))) + end + debut=fil(3) + bdebut=debut(1) //numero de la boite origine du lien ou de l'entree + pdebut=debut(2:prod(size(debut))) // ports origines + if pdebut==[] then // dimension implicite + fin=fil(4);pfin=fin(2:prod(size(fin))) + if pfin<>[] then + //meme dimension que le port d'entree du premier bloc connecte + pdebut=1:prod(size(pfin)) + else + if fin(1)>0 then // dimension d'entree du premier bloc aval + bfin=corresp(fin(1)) + pdebut=1:(insize(bfin+1)-insize(bfin)) + else // dimension de sortie du bloc amont + bd=corresp(bdebut) + pdebut=1:(outsize(bd+1)-outsize(bd)) + end + end + end + if bdebut>0 then, //le lien est issu d'un bloc + bdebut=corresp(bdebut) + ll0=1 + else // le lien correspond a une entree + if nnum>1 then, //l'entree attaque plusieurs blocs,on rajoute un gain + np=prod(size(pdebut)) + d(mo+np,mi+np)=eye(np,np) + if ms>0 then b(ms,mi+np)=0;c(mo+np,ms)=0;end + mo=mo+np + mi=mi+np + in=[in mi] + insize=[insize insize(inn)+np];inn=inn+1 + outsize=[outsize outsize(outn)+np];outn=outn+1 + bdebut=outn-1 + k(mi,mo)=0 + else + fin=fil(4) + bfin=corresp(fin(1)) + fin=fin(2:prod(size(fin))) + if fin==[] then //dimension implicite + fin=1:(insize(bfin+1)-insize(bfin)) + end + in=[in, (insize(bfin)-1)*ones(fin)+fin] + ll0=2 + end + end + for ll=ll0:nnum + fin=fil(ll+3) + bfin=fin(1) + if bfin >0 then + bfin=corresp(bfin) + pfin=fin(2:prod(size(fin))) + if pfin==[] then //dimension implicite + pfin=1:(insize(bfin+1)-insize(bfin)) + end + iin=(insize(bfin)-1)*ones(pfin)+pfin + iou=(outsize(bdebut)-1)*ones(pdebut)+pdebut + k(iin,iou)=eye(prod(size(iin)),prod(size(iou))) + else // le lien fournit une sortie + pfin=fin(2:prod(size(fin))) + if pfin==[] then //dimension implicite + pfin=1:prod(size(pdebut)) + end + if prod(size(pfin))<>prod(size(pdebut)) then + error(msprintf(gettext("%s: Wrong size for link from block %s.\n"),"bloc2ss",string(bdebut))) + end + out=[out, (outsize(bdebut)-1)*ones(pfin)+pdebut(pfin)] + end + end + end + if or(size(d')<>size(k)) then + error(msprintf(gettext("%s: Invalid sizes found during the process.\n"),"bloc2ss")) + end + sl=syslin([],a,b,c,d)/.(-k) + sl=sl(out,in) + sl(7)=dom + +endfunction + +function [lboites,lliens,lentrees,lsorties]=blocdext(syst) + //! + // + lboites=[] + lliens=[] + lentrees=[] + lsorties=[] + nsyst=size(syst) + for k=2:nsyst + obj=syst(k) + if type(obj)==15, if size(obj)>1 then + select part(obj(1),1) + case "t", + lboites=[lboites,k] + case "l" + obj2=obj(3) + + if obj2(1)>0 then + nobj=size(obj) + is_sortie=[] + for ko=3:nobj + objk=obj(ko) + if objk(1)<0 then is_sortie=[is_sortie,-objk(1)],end + end; + if is_sortie==[] then lliens=[lliens,k], + else lsorties(1,is_sortie)=k + end; + else lentrees(1,-obj2(1))=k, + end; + else error(msprintf(gettext("%s: Undefined type ''%s''.\n"),"bloc2ss",part(obj(1),1))) + end; + end,end + end; + if lsorties==[] then + error(msprintf(gettext("%s: No output found.\n"),"bloc2ss")), + end + if lentrees==[] then + error(msprintf(gettext("%s: No input found.\n"),"bloc2ss")), + end + if min(lsorties)==0 then + error(msprintf(gettext("%s: Some output(s) are undefined.\n"),"bloc2ss")), + end + if min(lentrees)==0 then + error(msprintf(gettext("%s: Some input(s) are undefined.\n"),"bloc2ss")), + end +endfunction diff --git a/modules/cacsd/macros/bode.bin b/modules/cacsd/macros/bode.bin Binary files differnew file mode 100755 index 000000000..0740d98d8 --- /dev/null +++ b/modules/cacsd/macros/bode.bin diff --git a/modules/cacsd/macros/bode.sci b/modules/cacsd/macros/bode.sci new file mode 100755 index 000000000..d1cba667e --- /dev/null +++ b/modules/cacsd/macros/bode.sci @@ -0,0 +1,207 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 1985-2010 - INRIA - Serge Steer +// 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 [] = bode(varargin) + rhs = size(varargin) + + if rhs == 0 then + s = poly(0, "s"); + h1 = syslin("c", (s^2+2*0.9*10*s+100)/(s^2+2*0.3*10.1*s+102.01)); + num = 22801+4406.18*s+382.37*s^2+21.02*s^3+s^4; + den = 22952.25+4117.77*s+490.63*s^2+33.06*s^3+s^4; + h2 = syslin("c", num/den); + + bode([h1; h2], 0.01, 100, ["h1"; "h2"]); + return; + end + + rad = %f; + if type(varargin($)) == 10 then + if varargin($) == "rad" then + rad = %t; + rhs = rhs-1; + if type(varargin($-1)) == 10 then + comments = varargin($-1); + rhs = rhs-1; + else + comments = []; + end + else + comments = varargin($); + rhs = rhs-1; + end + else + comments = []; + end + fname = "bode"; // For error messages + fmax = []; + discr = %f; // For Shannon limit + if or(typeof(varargin(1)) == ["state-space" "rational"]) then +// sys, fmin, fmax [,pas] or sys, frq + refdim = 1; // for error message + discr = varargin(1).dt<>"c"; + if rhs == 1 then // sys + [frq, repf] = repfreq(varargin(1), 1d-3, 1d3); + elseif rhs == 2 then // sys, frq + if size(varargin(2), 2) < 2 then + error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"), .. + fname, 2, 1)) + end + [frq, repf] = repfreq(varargin(1:rhs)); + elseif or(rhs == (3:4)) then // sys, fmin, fmax [,pas] + [frq, repf] = repfreq(varargin(1:rhs)); + else + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"), fname, 1, 5)) + end + [phi, d] = phasemag(repf); + if rhs >= 3 then fmax = varargin(3); end + elseif type(varargin(1)) == 1 then +// frq, db, phi [,comments] or frq, repf [,comments] + refdim = 2; + select rhs + case 2 then // frq,repf + frq = varargin(1); + if size(frq, 2) < 2 then + error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"), .. + fname, 1, 1)) + end + if size(frq, 2) <> size(varargin(2), 2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"), .. + fname, 1, 2)) + end + [phi, d] = phasemag(varargin(2)); + case 3 then // frq, db, phi + [frq, d, phi] = varargin(1:rhs); + if size(frq, 2) <> size(d, 2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"), .. + fname, 1, 2)) + end + if size(frq, 2) <> size(phi, 2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"), .. + fname, 1, 3)) + end + else + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"), fname, 2, 4)) + end + else + error(msprintf(_("%s: Wrong type for input argument #%d: Linear dynamical system or row vector of floats expected.\n"),fname,1)) + end + frq = frq'; + d = d'; + phi = phi'; + [n, mn] = size(d); + + if comments == [] then + hx = 0.48; + else + if size(comments, "*") <> mn then + error(mprintf(_("%s: Incompatible input arguments #%d and #%d: Same number of elements expected.\n"), ... + fname, refdim, rhs+1)) + end + hx = 0.43; + end + + fig = gcf(); + immediate_drawing = fig.immediate_drawing; + fig.immediate_drawing = "off"; + + sciCurAxes = gca(); + axes = sciCurAxes; + wrect = axes.axes_bounds; + + +// Magnitude + axes.axes_bounds = [wrect(1)+0, wrect(2)+0, wrect(3)*1.0, wrect(4)*hx*0.95]; + axes.data_bounds = [min(frq), min(d); max(frq), max(d)]; + axes.log_flags = "lnn"; + axes.grid = color("lightgrey")*ones(1, 3); + axes.axes_visible = "on"; + axes.clip_state = "clipgrf"; + if size(d, 2) > 1 & size(frq, 2) == 1 then + xpolys(frq(:, ones(1, mn)), d, 1:mn); + else + xpolys(frq, d, 1:mn); + end +// Set datatips info + e = gce(); + + for i=1:size(e.children, "*") + e.children(i).display_function = "formatBodeMagTip" + end + + if discr & fmax <> [] & max(frq) < fmax then + xpoly(max(frq)*[1; 1], axes.y_ticks.locations([1 $])); + e = gce(); + e.foreground = 5; + end + xtitle("", _("Frequency (Hz)"), _("Magnitude (dB)")); + +// Phase + axes = newaxes(); + axes.axes_bounds = [wrect(1)+0, wrect(2)+wrect(4)*hx, wrect(3)*1.0, wrect(4)*hx*0.95]; + axes.data_bounds = [min(frq), min(phi); max(frq), max(phi)]; + axes.log_flags = "lnn"; + axes.grid = color("lightgrey")*ones(1, 3); + axes.axes_visible = "on"; + axes.clip_state = "clipgrf"; + if size(phi, 2) > 1 & size(frq, 2) == 1 then + xpolys(frq(:, ones(1, mn)), phi, 1:mn); + else + xpolys(frq, phi, 1:mn); + end + ephi = gce(); +// Set datatips info + for i=1:size(ephi.children, "*") + ephi.children(i).display_function = "formatBodePhaseTip"; + end + + if discr & fmax <> [] & max(frq) < fmax then + xpoly(max(frq)*[1; 1], axes.y_ticks.locations([1 $])); + e = gce(); + e.foreground = 5; + end + xtitle("", _("Frequency (Hz)"), _("Phase (degree)")); +// Create legend + if comments <> [] then + c = captions(ephi.children, comments, "lower_caption"); + c.background = get(gcf(), "background"); + end + fig.immediate_drawing = immediate_drawing; +// Return to the previous scale + set("current_axes", sciCurAxes); + + if rad == %t then +// This function modifies the Bode diagrams for a rad/s display instead of Hz. +// h is a hanlde of a figure containing Bode diagrams. +// Ref: http://forge.scilab.org/index.php/p/cpge/source/tree/HEAD/macros/bode_Hz2rad_2.sci + labels = [_("Phase (degree)"); _("Magnitude (dB)")]; + pos_h = [9, 5]; + for k=1:2 + for i=1:size(fig.children(k).children, 1) + if fig.children(k).children(i).type == "Compound" + for j=1:size(fig.children(k).children(i).children, 1) + fig.children(k).children(i).children(j).data(:, 1) = fig.children(k).children(i).children(j).data(:, 1)*2*%pi; + end + + // h.children(k).title.text = h.children(k).y_label.text; + xmin1 = fig.children(k).data_bounds(1)*2*%pi; + xmax1 = fig.children(k).data_bounds(2)*2*%pi; + ymin1 = fig.children(k).data_bounds(3); + ymax1 = fig.children(k).data_bounds(4); + + rect = [xmin1, ymin1, xmax1, ymax1]; + nb_dec = log(xmax1/xmin1)/log(10); + fig.children(k).x_label.text = _("Frequency (rad/s)"); + fig.children(k).x_location = "bottom"; + fig.children(k).y_label.text = labels(k); + replot(rect, fig.children(k)); + end + end + end + end +endfunction diff --git a/modules/cacsd/macros/bode_asymp.bin b/modules/cacsd/macros/bode_asymp.bin Binary files differnew file mode 100755 index 000000000..884919f07 --- /dev/null +++ b/modules/cacsd/macros/bode_asymp.bin diff --git a/modules/cacsd/macros/bode_asymp.sci b/modules/cacsd/macros/bode_asymp.sci new file mode 100755 index 000000000..3ed4bd2c4 --- /dev/null +++ b/modules/cacsd/macros/bode_asymp.sci @@ -0,0 +1,189 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2013 - Scilab Enterprises - Paul Bignier +// Copyright (C) 09/2013 - A. Khorshidi +// +// 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 [] = bode_asymp(sl, w_min, w_max) + // Calling sequence: + // syntax: bode_asymp(sl, [w_min, w_max]) + // Arguments: + // sl: a linear system given by its transfer function representation or state-space form and defined by syslin. + // w_min, w_max: lower and upper frequency bounds (in rad/s) + // Description: + // This function plots asymptotes for the magnitude and phase graphs. + // Examples: + // s = %s; h = syslin("c", 1/(s+1)); scf(10001); bode(h); bode_asymp(h) + // s = %s; h = syslin("c", 1/(s+1)); scf(10002); gainplot(h); bode_asymp(h) + // Ref: + // http://forge.scilab.org/index.php/p/cpge/source/tree/HEAD/macros/REP_FREQ_pre_simulate.sci + + rhs = argn(2); + + if and(typeof(sl) <> ["state-space" "rational"]) then + msg = _("Wrong type for argument #%d: Rational or State-space matrix expected.\n"); + error(msprintf(msg, 1)) + return; + end + + typeSL = typeof(sl); + + for elem=1:size(sl, "r") // Individually draw each asymptote of "sl" elements (row vector). + if typeSL == "rational" then + h = sl(elem, 1); + else + h = clean(ss2tf(sl(elem, 1)), 1e-8); + // Also removing all the coefficients smaller than < 1e-8 + end + + root_num = roots(h.num); + root_den = roots(h.den); + + if (find(root_num==0)) + disp("Problem class of system is negative") + end + rac_nul = find(root_den==0); + alpha = length(rac_nul); + var = "s"; + domain = h.dt; + if type(domain) == 1 then + var = "z"; + elseif domain == "c" then + var = "s"; + elseif domain == "d" then + var = "z"; + end + if domain == [] then + var = "s"; + if type(h.D) == 2 then + var = varn(h.D); + end + end + s = poly(0, var); + msg = _("%s: Wrong value for input argument #%d: Evaluation failed.\n") + try K = horner(h*s^alpha, 0); catch error(msprintf(msg, "bode_asymp")); end + + root_den(rac_nul) = []; // Removing the zeros + + if length([find(abs(root_num)>1e8) find(abs(root_num)<1e-8)]) > 0 then + disp("Extreme root removed: "+string(root_num([find(abs(root_num)>1e8) find(abs(root_num)<1e-8)])')) + root_num([find(abs(root_num)>1e8) find(abs(root_num)<1e-8)]) = []; + end + if length([find(abs(root_den)>1e8) find(abs(root_den)<1e-8)]) > 0 then + disp("Extreme root removed: "+string(root_den([find(abs(root_den)>1e8) find(abs(root_den)<1e-8)])')) + root_den([find(abs(root_den)>1e8) find(abs(root_den)<1e-8)]) = []; + end + + i = 1; + puls = []; + order = []; + while i<=length(root_num) // Real root + if isreal(root_num(i), 0) then + puls = [puls -root_num(i)]; + order = [order 1]; + i = i+1; + else // Complex root + xi = 1/sqrt(1+(imag(root_num(i))/real(root_num(i)))^2); + puls = [puls -real(root_num(i))/xi]; + i = i+2; + order = [order 2]; + end + end + i = 1; + while i<=length(root_den) // Real root + if isreal(root_den(i), 0) then + puls = [puls -root_den(i)]; + order = [order -1]; + i = i+1; + else // Complex root + xi = 1/sqrt(1+(imag(root_den(i))/real(root_den(i)))^2); + puls = [puls -real(root_den(i))/xi]; + order = [order -2]; + i = i+2; + end + end + + [puls, ind] = gsort(puls, "g", "i"); + order = order(ind); + + asym = [-20*alpha]; + phas = [-90*alpha]; + i = 1; + while i<=length(puls) + new_dir = asym($)+order(i)*20; + asym = [asym new_dir]; + new_arg = phas($)+order(i)*90; + phas = [phas new_arg]; + i = i+1; + end + + // bode(h, w_min, w_max) + fig = gcf(); + try sca(fig.children(1)); catch + msg = _("ERROR: %s: bode() or gainplot() must be called before bode_asymp() and graphic window must still be running.\n"); + error(msprintf(msg, "bode_asymp")) + end + + if length(fig.children) == 1 then + flag = 1; + else + flag = 0; + end + + if rhs == 1 then + wmin = fig.children(1).data_bounds(1, 1); // Minimal frequency, w_min + wmax = fig.children(1).data_bounds(2, 1); // Maximal frequency, w_max + else + wmin = w_min; + wmax = w_max; + end + puls_to_plot = []; + + for p=real(puls) + if p >= wmin & p <= wmax then + puls_to_plot($+1) = p; + end + end + puls = [wmin puls_to_plot' wmax]; + // End change DV + + eq_asymp = [20*log10(K/wmin^alpha)]; + puls_p = []; + phas($+1) = phas($); + eq_phas = [phas(1)]; + i = 2; + while i<=length(puls) + eq_asymp = [eq_asymp eq_asymp($)+asym(i-1)*log10(puls(i)/puls(i-1))]; + puls_p = [puls_p puls(i-1) puls(i)]; + eq_phas = [eq_phas phas(i-1) phas(i)]; + i = i+1; + end + + // Adapt abscissae to current unit (Hertz or rad/s) + if fig.children(1).x_label.text == "Frequency (Hz)" then + puls = puls./(2*%pi); + puls_p = puls_p./(2*%pi); + end + + // Change the color of asymptote: + color_asymp = ["b--", "g--", "c--", "m--", "r--"]; + rep = modulo(elem, 5); // This line will be useful if the number of systems is more than five. + if rep == 0 then + rep = 1; + end + + if flag == 0 then + plot(puls_p, eq_phas(1:$-1), color_asymp($-rep)); + sca(fig.children(2)); + plot(puls, eq_asymp, color_asymp(rep)); + elseif flag == 1 then + plot(puls, eq_asymp, color_asymp(rep)); + fig.children.title.text = "Gainplot"; + end + end + +endfunction diff --git a/modules/cacsd/macros/bstap.bin b/modules/cacsd/macros/bstap.bin Binary files differnew file mode 100755 index 000000000..d5d208a7f --- /dev/null +++ b/modules/cacsd/macros/bstap.bin diff --git a/modules/cacsd/macros/bstap.sci b/modules/cacsd/macros/bstap.sci new file mode 100755 index 000000000..5ae56b206 --- /dev/null +++ b/modules/cacsd/macros/bstap.sci @@ -0,0 +1,39 @@ +// 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 [Q]=bstap(sl) + // Best approximant Q of Sl + // ||Sl-Q|| = ||Tsl|| + // inf + // ||Tsl|| norm of hankel operator + //-- sl is assumed antistable + //-- Q : best stable approximation of Sl + //! + //balancing + //----------------------------------- + + slt=gtild(sl);slt=balreal(slt);sl=gtild(slt), + // D such that DB1'+sC1 = 0 , DD' = s**2I + //------------------------------------------------- + [a,b,c]=sl(2:4),[n,n]=size(a),[m,n]=size(c), + x=-obs_gram(sl),s=x(1,1), + [w,r]=rowcomp(x-s*eye()),r=n-r, + b1=b(1:r,:),c1=c(:,1:r), + [u1,s1,v1]=svd(-c1'),[u2,s2,v2]=svd(b1), + v2=v2(:,1:m),dd=s*v1*v2', + // + //-------------------------------- + a22=a(r+1:n,r+1:n), + b2=b(r+1:n,:),c2=c(:,r+1:n), + sig=x(r+1:n,r+1:n), + bb=-inv(s**2*eye()-sig*sig)*(sig*b2+s*c2'*dd), + aa=-(a22+b2*bb')',cc=c2*sig+dd*b2', + Q=syslin("c",aa,bb,cc,dd), +endfunction diff --git a/modules/cacsd/macros/buildmacros.bat b/modules/cacsd/macros/buildmacros.bat new file mode 100755 index 000000000..c4e35ec40 --- /dev/null +++ b/modules/cacsd/macros/buildmacros.bat @@ -0,0 +1 @@ +@..\..\..\bin\scilex -nwni -ns -e exec('buildmacros.sce');quit;
\ No newline at end of file diff --git a/modules/cacsd/macros/buildmacros.sce b/modules/cacsd/macros/buildmacros.sce new file mode 100755 index 000000000..862ddf8f1 --- /dev/null +++ b/modules/cacsd/macros/buildmacros.sce @@ -0,0 +1,16 @@ +//------------------------------------ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - Allan CORNET +// +// 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 +//------------------------------------ +if (isdef("genlib") == %f) then + exec(SCI+"/modules/functions/scripts/buildmacros/loadgenlib.sce"); +end +//------------------------------------ +genlib("cacsdlib","SCI/modules/cacsd/macros",%f,%t); +//------------------------------------ diff --git a/modules/cacsd/macros/cainv.bin b/modules/cacsd/macros/cainv.bin Binary files differnew file mode 100755 index 000000000..c13deae4d --- /dev/null +++ b/modules/cacsd/macros/cainv.bin diff --git a/modules/cacsd/macros/cainv.sci b/modules/cacsd/macros/cainv.sci new file mode 100755 index 000000000..0e2e0691c --- /dev/null +++ b/modules/cacsd/macros/cainv.sci @@ -0,0 +1,103 @@ +// 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 [X,dims,J,Y,k,Z]=cainv(Sl,Alfa,Beta,flag) + //CA invariant subspace: dual of abinv + //Finds orthogonal bases X and Y and output injection J + //such that the abcd matrices of Sl in bases (X,Y) are displayed as: + // + // [A11,*,*,*,*,*] [*] + // [0,A22,*,*,*,*] [*] + // X'*(A+J*C)*X = [0,0,A33,*,*,*] X'*(B+J*D) = [*] + // [0,0,0,A44,*,*] [0] + // [0,0,0,0,A55,*] [0] + // [0,0,0,0,0,A66] [0] + // + // Y*C*X = [0,0,C13,*,*,*] Y*D = [*] + // [0,0,0,0,0,C26] [0] + // + // dims=[nd1,nu1,dimS,dimSg,dimN] defines the partition of A matrix and k the partition + // of [C,D] matrix. + // eigenvalues of A11 (nd1 x nd1) are unstable + // eigenvalues of A22 (nu1-nd1 x nu1-nd1) are stable + // pair (A33, C13) (dimS-nu1 x dimS-nu1, k x dimS-nu1) is observable, eigenvalues of A33 set to Alfa + // A44 (dimSg-dimS x dimSg-dimS) is unstable + // A55 (dimN-dimSg,dimN-dimSg) is stable + // pair (A66,C26) (nx-dimN x nx-dimN, ) is observable, eigenvalues of A66 set to Beta. + // + // dimS first columns of X span S= smallest (C,A) invariant + // subspace which contains Im(B). + // dimSg first columns of X span Sg + // dimN first columns of X span N=S+V + // dimS=0 iff B(ker(D))=0 + // + // DDEP: dot(x)=A x + Bu + Gd + // y= Cx (observation) + // z= Hx (z=variable to be estimated, d=disturbance) + // Find: dot(w) = Fw + Ey + Ru such that + // zhat = Mw + Ny + // z-Hx goes to zero at infinity + // Solution exists iff Ker H contains Sg(A,C,G) inter KerC + //i.e. H is such that: + // For any W which makes a column compression of [Xp(1:dimSg,:);C] + // with Xp=X' and [X,dims,J,Y,k,Z]=cainv(syslin('c',A,G,C)); + // [Xp(1:dimSg,:);C]*W = [0 | *] one has + // H*W = [0 | *] (with at least as many columns as above). + + [LHS,RHS]=argn(0); + if RHS==1 then Alfa=-1;Beta=-1;flag="ge";end + if RHS==2 then Beta=Alfa;flag="ge";end + if RHS==3 then flag="ge";end + if RHS==4 then + if type(flag)~=10 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: String array expected.\n"),"cainv",4)); + end + if size(flag,"*")<>1 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A string expected.\n"),"cainv",4)); + end + end + [X,ddims,F,U,k,Z]=abinv(Sl',Beta,Alfa,flag); + [nx,nx]=size(X); + select flag + case "ge" + nr=ddims(1);nvg=ddims(2);nv=ddims(3);noc=ddims(4);nos=ddims(5); + nd1=nx-nos;nu1=nx-noc;dimS=nx-nv;dimSg=nx-nvg;dimN=nx-nr; + n6=1+ddims(5):nx; + n5=1+ddims(4):ddims(5); + n4=1+ddims(3):ddims(4); + n3=1+ddims(2):ddims(3); + n2=1+ddims(1):ddims(2); + n1=1:ddims(1); + //nr=1:nr;nzs=nr+1:nr+nvg;nzi=nvg+1:nv; + X=[X(:,n6),X(:,n5),X(:,n4),X(:,n3),X(:,n2),X(:,n1)]; + J=F';Z=Z';Y=U';Y=[Y(k+1:$,:);Y(1:k,:)]; + dims=[nd1,nu1,dimS,dimSg,dimN]; + return; + case "st" + dims=nx-ddims;dims=dims($:-1:1); + n5=1+ddims(4):nx; + n4=1+ddims(3):ddims(4); + n3=1+ddims(2):ddims(3); + n2=1+ddims(1):ddims(2); + n1=1:ddims(1); + X=[X(:,n5),X(:,n4),X(:,n3),X(:,n2),X(:,n1)]; + J=F';Z=Z';Y=U';Y=[Y(k+1:$,:);Y(1:k,:)]; + return; + case "pp" + dims=nx-ddims;dims=dims($:-1:1); + n4=1+ddims(3):nx; + n3=1+ddims(2):ddims(3); + n2=1+ddims(1):ddims(2); + n1=1:ddims(1); + X=[X(:,n4),X(:,n3),X(:,n2),X(:,n1)]; + J=F';Z=Z';Y=U';Y=[Y(k+1:$,:);Y(1:k,:)]; + return; + end +endfunction diff --git a/modules/cacsd/macros/calfrq.bin b/modules/cacsd/macros/calfrq.bin Binary files differnew file mode 100755 index 000000000..e2fddb2b9 --- /dev/null +++ b/modules/cacsd/macros/calfrq.bin diff --git a/modules/cacsd/macros/calfrq.sci b/modules/cacsd/macros/calfrq.sci new file mode 100755 index 000000000..524bf49c3 --- /dev/null +++ b/modules/cacsd/macros/calfrq.sci @@ -0,0 +1,276 @@ +// 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 [frq, bnds, splitf] = calfrq(h, fmin, fmax) + //! + + eps = 1.d-14 //minimum absolute lower frequency + k = 0.001 // Minimum relative prediction error in the nyquist plan + epss = 0.002 // minimum frequency distance with a singularity + nptmax = 5000 //maximum number of discretization points + tol = 0.01 // Tolerance for testing pure imaginary numbers + + // Check inputs + // ------------ + if and(typeof(h) <> ["state-space" "rational"]) + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"), "calfrq", 1)) + end + if typeof(h) == "state-space" then + h = ss2tf(h) + end + + [m, n] = size(h.num) + dom = h("dt") + select dom + case "d" then + dom = 1 + case [] then + error(96, 1) + case 0 then + error(96, 1) + end; + + if type(dom) == 1 then + nyq_frq = 1/2/dom; + if fmax > nyq_frq then + warning(msprintf(gettext("%s: Frequencies beyond Nyquist frequency are ignored.\n"), "calfrq")); + fmax = min(fmax, nyq_frq) + end + if fmin < -nyq_frq then + warning(msprintf(gettext("%s: Negative frequencies below Nyquist frequency are ignored.\n"), "calfrq")); + fmin = max(fmin, -nyq_frq) + end + end + // Use symmetry to reduce the range + // -------------------------------- + if fmin < 0 & fmax >= 0 then + [frq, bnds, splitf] = calfrq(h, eps, -fmin) + ns1 = size(splitf, "*")-1; + nsp = size(frq, "*"); + bnds = [bnds(1), bnds(2), -bnds(4), -bnds(3)]; + + if fmax > eps then + if fmax == -fmin then + splitf = [1, (nsp+2)*ones(1,ns1)-splitf($:-1:2), nsp*ones(ns1)+splitf(2:$)]; + bnds = [bnds(1), bnds(2), min(bnds(3), -bnds(3)), max(bnds(4), -bnds(4))]; + frq = [-frq($:-1:1), frq] + else + [frq2, bnds2, splitf2] = calfrq(h, eps, fmax); + ns2 = size(splitf2,"*")-1 + splitf = [1, (nsp+2)*ones(1,ns1)-splitf($:-1:2), nsp*ones(ns2)+splitf2(2:$)]; + bnds = [min(bnds(1), bnds2(1)), max(bnds(2), bnds2(2)),... + min(bnds(3), bnds2(3)), max(bnds(4), bnds2(4))]; + frq = [-frq($:-1:1), frq2] + end + return + else + frq = -frq($:-1:1); + nsp = size(frq, "*"); + + splitf = [1, (nsp+2)*ones(1, ns1)-splitf($:-1:2)] + bnds = bnds; + return; + end + elseif fmin < 0 & fmax <= 0 then + [frq, bnds, splitf] = calfrq(h, -fmax, -fmin) + ns1 = size(splitf, "*")-1; + frq = -frq($:-1:1); + nsp = size(frq, "*"); + splitf = [1, (nsp+2)*ones(1, ns1)-splitf($:-1:2)] + bnds = [bnds(1), bnds(2), -bnds(4), -bnds(3)]; + return; + elseif fmin >= fmax then + error(msprintf(gettext("%s: Wrong value for input arguments #%d and #%d: %s < %s expected.\n"),.. + "calfrq", 2, 3, "fmin", "fmax")); + end + + // Compute dicretisation over a given range + // ---------------------------------------- + + + splitf = [] + if fmin == 0 then fmin = min(1d-14, fmax/10);end + // + denh = h("den"); numh = h("num") + l10 = log(10) + + // Locate singularities to avoid them + // ---------------------------------- + if dom == "c" then + c = 2*%pi; + // selection function for singularities in the frequency range + deff("f=%sel(r, fmin, fmax, tol)",["f = [],"; + "if prod(size(r)) == 0 then return, end"; + "f = imag(r(find((abs(real(r))<=tol*abs(r))&(imag(r)>=0))))"; + "if f <> [] then f = f(find((f>fmin-tol)&(f<fmax+tol))); end"]); + else + c = 2*%pi*dom + // selection function for singularities in the frequency range + deff("[f] = %sel(r, fmin, fmax, dom, tol)",["f = [],"; + "if prod(size(r)) == 0 then return, end"; + "f = r(find( ((abs(abs(r)-ones(r)))<=tol)&(imag(r)>=0)))"; + "if f <> [] then "; + " f = atan(imag(f), real(f)); nf = prod(size(f))"; + " for k=1:nf,"; + " kk = int((fmax-f(k))/(2*%pi))+1;"; + " f = [f; f(1:nf)+2*%pi*kk*ones(nf, 1)];"; + " end;" + " f = f(find((f>fmin-tol)&(f<fmax+tol)))"; + "end"]); + end + + sing = [];zers = []; + fmin = c*fmin, fmax = c*fmax; + + for i=1:m + sing = [sing; %sel(roots(denh(i), "e"), fmin, fmax, tol)]; + end + + pp = gsort(sing', "g", "i"); npp = size(pp, "*");//' + + // singularities just on the left of the range + kinf = find(pp<fmin) + if kinf <> [] then + fmin = fmin+tol + pp(kinf) = [] + end + + // singularities just on the right of the range + ksup = find(pp>=fmax) + if ksup <> [] then + fmax = fmax-tol + pp(ksup) = [] + end + + // check for nearly multiple singularities + if pp <> [] then + dpp = pp(2:$)-pp(1:$-1) + keq = find(abs(dpp)<2*epss) + if keq <> [] then pp(keq) = [], end + end + + if pp <> [] then + frqs = [fmin real(matrix([(1-epss)*pp; (1+epss)*pp], 2*size(pp, "*"), 1)') fmax] + //' + else + frqs = [fmin fmax] + end + nfrq = size(frqs, "*"); + + // Evaluate bounds of nyquist plot + //------------------------------- + xt = []; Pas = [] + for i=1:2:nfrq-1 + w = logspace(log(frqs(i))/log(10), log(frqs(i+1))/log(10), 100); + xt = [xt, w] + Pas = [Pas w(2)-w(1)] + end + if dom == "c" then + rf = freq(h("num"), h("den"), %i*xt); + else + rf = freq(h("num"), h("den"), exp(%i*xt)); + end + // + xmin = min(real(rf)); xmax = max(real(rf)); + ymin = min(imag(rf)); ymax = max(imag(rf)); + bnds = [xmin xmax ymin ymax]; + dx = max([xmax-xmin, 1]); dy = max([ymax-ymin, 1]); + + // Compute discretization with a step adaptation method + // ---------------------------------------------------- + frq = []; + i = 1; + nptr = nptmax; // number of unused discretization points + l10last = log10(frqs($)); + while i<nfrq + f0 = frqs(i); fmax = frqs(i+1); + while f0==fmax do + i = i+2; + f = frqs(i); fmax = frqs(i+1); + end + frq = [frq, f0]; + pas = Pas(floor(i/2)+1) + splitf = [splitf size(frq, "*")]; + + f = min(f0+pas, fmax); + + if dom == "c" then // Continuous case + while f0<fmax + rf0 = freq(h("num"), h("den"), (%i*f0)); + rfc = freq(h("num"), h("den"), %i*f); + // compute prediction error + epsd = pas/100; // epsd = 1.d-8 + + rfd = (freq(h("num"), h("den"), %i*(f0+epsd))-rf0)/(epsd); + rfp = rf0+pas*rfd; + + e = max([abs(imag(rfp-rfc))/dy; abs(real(rfp-rfc))/dx]) + if e > k then rf0 = freq(h("num"), h("den"), (%i*f0)); + rfc = freq(h("num"), h("den"), %i*f); + // compute prediction error + epsd = pas/100; // epsd = 1.d-8 + + rfd = (freq(h("num"), h("den"), %i*(f0+epsd))-rf0)/(epsd); + rfp = rf0+pas*rfd; + + e = max([abs(imag(rfp-rfc))/dy; abs(real(rfp-rfc))/dx]) + // compute minimum frequency logarithmic step to ensure a maximum + //of nptmax points to discretize + pasmin = f0*(10^((l10last-log10(f0))/(nptr+1))-1) + pas = pas/2 + if pas < pasmin then + pas = pasmin + frq = [frq, f]; nptr = max([1, nptr-1]) + f0 = f; f = min(f0+pas, fmax) + else + f = min(f0+pas, fmax) + end + elseif e < k/2 then + pas = 2*pas + frq = [frq, f]; nptr = max([1, nptr-1]) + f0 = f; f = min(f0+pas, fmax), + else + frq = [frq, f];nptr = max([1, nptr-1]) + f0 = f; f = min(f0+pas, fmax), + end + end + else // Discrete case + pas = pas/dom + while f0<fmax + rf0 = freq(h("num"), h("den"), exp(%i*f0)) + rfd = dom*(freq(h("num"), h("den"), exp(%i*(f0+pas/100)))-rf0)/(pas/100); + rfp = rf0+pas*rfd + rfc = freq(h("num"), h("den"), exp(%i*f)); + e = max([abs(imag(rfp-rfc))/dy; abs(real(rfp-rfc))/dx]) + if e > k then + pasmin = f0*(10^((l10last-log10(f0))/(nptr+1))-1) + pas = pas/2 + if pas < pasmin then + pas = pasmin + frq = [frq, f]; nptr = max([1, nptr-1]) + f0 = f; f = min(f0+pas, fmax) + else + f = min(f0+pas, fmax) + end + elseif e < k/2 then + pas = 2*pas + frq = [frq, f]; nptr = max([1, nptr-1]) + f0 = f; f = min(f0+pas, fmax), + else + frq = [frq, f]; nptr = max([1, nptr-1]) + f0 = f; f = min(f0+pas, fmax), + end + end + end + i = i+2 + end + frq(size(frq, "*")) = fmax + frq = frq/c; +endfunction diff --git a/modules/cacsd/macros/canon.bin b/modules/cacsd/macros/canon.bin Binary files differnew file mode 100755 index 000000000..20dad4560 --- /dev/null +++ b/modules/cacsd/macros/canon.bin diff --git a/modules/cacsd/macros/canon.sci b/modules/cacsd/macros/canon.sci new file mode 100755 index 000000000..60aeef6cd --- /dev/null +++ b/modules/cacsd/macros/canon.sci @@ -0,0 +1,66 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [ac,bc,u,ind]=canon(a,b) + //[ac,bc,u,ind]=canon(a,b) gives the canonical controllable form + //of the pair (a,b). + // + //ind controllability indices, + //ac,bc canonical form + //u current basis i.e. ac=inv(u)*a*u,bc=inv(u)*b + // + //See also : obsv_mat, cont_mat, ctr_gram, contrss + //! + //1: block-hessenberg form + + // Was : [ac,bc,u,ro]=contr(a,b,[1.d-10*norm([a,b],1),1.d-10]); + [n,u,ro,V,ac,bc]=contr(a,b,1.d-10*norm([a,b],1)); + //2:zeroing what is to the right of under-diagonal blocks + [na,ni]=size(b);[l,k]=size(ro);k0=na+1;k1=k0-ro(k); + for kk=k:-1:2, + k2=k1-ro(kk-1);rows=k1:k0-1;cols=k1:na;intsc=k2:k1-1; + i=eye(na,na);i(intsc,cols)=-ac(rows,intsc)\ac(rows,cols); + im1=2*eye()-i;ac=im1*ac*i,bc=im1*bc;u=u*i;k0=k1;k1=k2; + end; + //3: compression of under-the-diagonal blocks + i=eye(na,na);n=1;m=ro(1)+1; + for kk=1:k-1, + c=n:n+ro(kk)-1;z=ac(m:m+ro(kk+1)-1,c); + [x,s,v]=svd(z);i(c,c)=v;n=n+ro(kk);m=m+ro(kk+1); + end; + ac=i'*ac*i,bc=i'*bc;u=u*i; + //4. normalization of blocks + j=eye(na,na);i=eye(na,na);k0=na+1;k1=k0-ro(k); + for kk=k:-1:2, + k2=k1-ro(kk-1);rows=k1:k0-1;long=k2:k2+k0-k1-1; + i=eye(na,na);j=eye(na,na); + z=ac(rows,long);j(long,long)=z; + i(long,long)=inv(z); + ac=j*ac*i,bc=j*bc;u=u*i;k0=k1;k1=k2; + end; + // controllability indices + ind=0*ones(1,ni);[xx,mi]=size(ro); + for k=1:ni,for kk=1:mi, + if ro(kk)>=k then ind(k)=ind(k)+1;end; + end;end + //final permutation: + v=ones(1,na); + for k=1:ind(1)-1, + index=sum(ro(1:k))+1;v(k+1)=index; + end; + k0=1;kmin=ind(1)+1; + for kk=2:ni, + numb=ind(kk); + kmax=kmin+numb-1; + v(kmin:kmax)=v(k0:k0+numb-1)+ones(1,ind(kk)); + k0=kmin;kmin=kmax+1; + end; + ac=ac(v,v),bc=bc(v,:),u=u(:,v); +endfunction diff --git a/modules/cacsd/macros/ccontrg.bin b/modules/cacsd/macros/ccontrg.bin Binary files differnew file mode 100755 index 000000000..33538cc91 --- /dev/null +++ b/modules/cacsd/macros/ccontrg.bin diff --git a/modules/cacsd/macros/ccontrg.sci b/modules/cacsd/macros/ccontrg.sci new file mode 100755 index 000000000..41f6d1fb9 --- /dev/null +++ b/modules/cacsd/macros/ccontrg.sci @@ -0,0 +1,228 @@ +// 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 [K]=ccontrg(PP,r,Gamma); + //*********************************** + // returns a realization of the central controller for the + // general problem using the formulas in Gahinet, 92 + // Note that Gamma must be > gopt (output of gamitg) + + + // PP contains the parameters of plant realization (sylin list) + // b = ( b1 , b2 ) , c = ( c1 ) , d = ( d11 d12) + // ( c2 ) ( d21 d22) + // r(1) and r(2) are the dimensions of d22 (rows x columns) + if argn(2)<>3 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected.\n"),"ccontrg",3)) + end + + if typeof(PP)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"ccontrg",1)) + end + if PP.dt<>"c" then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Continuous time system expected.\n"),"ccontrg",1)) + end + if typeof(r)<>"constant"|~isreal(r) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real vector expected.\n"),"ccontrg",2)) + end + if size(r,"*")<>2 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: %d expected.\n"),"ccontrg",2,2)) + end + r=int(r); + if or(r<=0) then + error(msprintf(gettext("%s: Wrong values for input argument #%d: Elements must be positive.\n"),"ccontrg",2)) + end + + //parameter recovery + [a,b1,b2,c1,c2,d11,d12,d21,d22]=smga(PP,r); + + //dimensions + [na,na]=size(a); nh=2*na; + [p1,m2]=size(d12), + [p2,m1]=size(d21), + gs=Gamma**2; + + //HAMILTONIAN SETUP + //------------------ + sh22=m1+m2; + h11=[a,0*eye(a);-c1'*c1,-a']; + h12=[-b1,-b2;c1'*d11,c1'*d12]; + h21=[d11'*c1,b1';d12'*c1,b2']; + h22=gs*eye(m1,m1); h22(sh22,sh22)=0; + h22=h22-[d11,d12]'*[d11,d12]; + + sj22=p1+p2; + j11=[a',0*eye(a);-b1*b1',-a]; + j12=[-c1',-c2';b1*d11',b1*d21'] + j21=[d11*b1',c1;d21*b1',c2]; + j22=gs*eye(p1,p1); j22(sj22,sj22)=0; + j22=j22-[d11;d21]*[d11;d21]'; + + + + //computation of Xinf and Yinf + //----------------------------- + + //compute orthon. bases of the negative inv. subspaces. + + [q,r]=qr([h12;h22]); + q12=q(1:nh,sh22+1:nh+sh22); q22=q(nh+1:nh+sh22,sh22+1:nh+sh22); + hr=q12'*h11+q22'*h21; + [uh,dh]=schur(hr,q12',"c"); + px=uh(1:na,1:na); qx=uh(na+1:nh,1:na); + + [q,r]=qr([j12;j22]); + q12=q(1:nh,sj22+1:nh+sj22); q22=q(nh+1:nh+sj22,sj22+1:nh+sj22); + jr=q12'*j11+q22'*j21; + [uj,dj]=schur(jr,q12',"c"); + py=uj(1:na,1:na); qy=uj(na+1:nh,1:na); + + + //computation of M,N + [uz,sz,vz]=svd(qx'*qy/gs-px'*py); + sz=sqrt(sz); + + + //DETERMINATION OF DK + //------------------- + + [u,s,v]=svd(d12); r12=max(size(find(diag(s) > 1.0e-10))); + [w,p,z]=svd(d21); r21=max(size(find(diag(p) > 1.0e-10))); + u1=u(:,1:r12); v1=v(:,1:r12); w1=w(:,1:r21); z1=z(:,1:r21); + s1=s(1:r12,1:r12); ph1=p(1:r21,1:r21); + d11tr=u'*d11*z; + + [g0,d0]=parrt(d11tr(r12+1:p1,r21+1:m1),d11tr(r12+1:p1,1:r21),.. + d11tr(1:r12,r21+1:m1),r12,r21); + dk=v1*s1\(d0-d11tr(1:r12,1:r21))/ph1*w1'; + + + //DETERMINATION OF BK, CK + //----------------------- + + hd11=(eye(p1,p1)-u1*u1')*d11; + hb1=b1-b2*v1*(s1\(u1'*d11)); + that=dk*c2*px+v1*s1\(u1'*c1*px+s1\v1'*b2'*qx+.. + (d0*z1'+u1'*d11*(eye(m1,m1)-z1*z1'))*.. + ((gs*eye(m1,m1)-hd11'*hd11)\(hb1'*qx+hd11'*c1*px))); + + td11=d11*(eye(m1,m1)-z1*z1'); + tc1=c1-(d11*z1/ph1)*w1'*c2; + ttil=py'*b2*dk+(py'*b1*z1+qy'*c2'*w1/ph1+.. + ((qy'*tc1'+py'*b1*td11')/(gs*eye(p1,p1)-td11*td11'))*.. + ((eye(p1,p1)-u1*u1')*d11*z1+u1*d0))/ph1*w1'; + + ck=-that*uz/sz; bk=-sz\vz'*ttil; + + + //just checking... + x=qx/px; y=qy/py; + d12p=pinv(d12); d21p=pinv(d21); + thh=d12p*(c1+d12p'*b2'*x)+dk*c2+(d12p*d11+dk*d21)/.. + (gs*eye(m1,m1)-hd11'*hd11)*((b1-b2*d12p*d11)'*x+hd11'*c1); + thh=thh*px; + ttt=(b1+y*c2'*d21p')*d21p+b2*dk+(y*tc1'+b1*td11')/.. + (gs*eye(p1,p1)-td11*td11')*(d11*d21p+d12*dk); + ttt=py'*ttt; + + nmin=max(norm(hd11),norm(td11)); + ncom=norm(d11+d12*dk*d21); + + + //DETERMINATION OF AK + //------------------- + + ca=a+b2*dk*c2; cb=b1+b2*dk*d21; cc=c1+d12*dk*c2; Cd=d11+d12*dk*d21; + ak=py'*b2*that+ttil*c2*px-py'*ca*px-qy'*ca'*qx/gs+.. + [-qy'*cc'/Gamma,py'*cb-ttil*d21]/.. + [Gamma*eye(p1,p1),Cd;Cd',Gamma*eye(m1,m1)]*.. + [cc*px-d12*that;-cb'*qx/Gamma]; + ak=sz\(vz'*ak*uz)/sz; + + + + K=syslin("c",ak,bk,ck,dk); + +endfunction + +function [go,xo]=parrt(a,b,c,rx,cx); + // + // [go,xo]=par(a,b,c,rx,cx) solves the minimization (Parrot) problem: + // + // || a b || + // min || || + // X || c x ||2 + // + // an explicit solution is + // 2 T -1 T + // Xo = - c ( go I - a a) a b + // where T T + // go = max ( || (a , b) || , || (a , c) || ) + // + // rx and cx are the dimensions of Xo (optional if a is nondegenerate) + // + //! + //constant + TOLA=1.0e-8; // threshold used to discard near singularities in gs I - A'*A + + go=max(norm([a b]),norm([a;c])); + [ra,cb]=size(b); [rc,ca]=size(c); xo=0; + + + //MONITOR LIMIT CASES + //-------------------- + if ra==0 | ca == 0 | go == 0 then xo(rx,cx)=0; return; end + + + + //COMPUTE Xo IN NONTRIVIAL CASES + //------------------------------ + + gs=(go**2); + [u,s,v]=svd(a); + + //form gs I - s' * s + ns=min(ra,ca); + if size(s,1)>1 then + d=diag(s); + else + d=s(1) + end + dd=gs*ones(d)-d**2; + + + //isolate the non (nearly) singular part of gs I - A'*A + nnz1=nthresh(dd/go,TOLA); + nd=ns-nnz1; //number of singular values thresholded out + + //compute xo + if nnz1==0 then + xo(rc,cb)=0; + else + unz=u(:,nd+1:ra); + vnz=v(:,nd+1:ca); + s=s(nd+1:ra,nd+1:ca); + for i=1:nnz1 + s(i,i)=s(i,i)/dd(i+nd); + end + xo=-c*vnz*s'*unz'*b; + end +endfunction + +function n=nthresh(d,tol) + n=find(d<=tol,1) + if n==[] then + n=size(d,"*"), + else + n=n-1 + end +endfunction + + diff --git a/modules/cacsd/macros/cfspec.bin b/modules/cacsd/macros/cfspec.bin Binary files differnew file mode 100755 index 000000000..a4caa406f --- /dev/null +++ b/modules/cacsd/macros/cfspec.bin diff --git a/modules/cacsd/macros/cfspec.sci b/modules/cacsd/macros/cfspec.sci new file mode 100755 index 000000000..2ef0d73a9 --- /dev/null +++ b/modules/cacsd/macros/cfspec.sci @@ -0,0 +1,28 @@ +// 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 [gm]=cfspec(g) + //[gm]=cfspec(g) computes a co-spectral factorization: + // g = gm*gtild(gm) + //with stable gm and gm^-1 ( gm^-1 = invsyslin(gm) ). + //-- g: syslin list defining the linear system g + //-- gm: + //Assumptions: + //- g is invertible ( inv(D) exists ), + //- g and g^1 (invsyslin(g)) have no poles on the imaginary axis. + //- gtild(g) = g. + // (poles and zeros of g are symmetric wrt imaginary axis)) + //- g(+oo) = D is positive definite. + //! + + if type(g)==1 then gm=chol(g),return,end, + gm=fspec(g'), + gm=gm' +endfunction diff --git a/modules/cacsd/macros/cleanmacros.bat b/modules/cacsd/macros/cleanmacros.bat new file mode 100755 index 000000000..5079dfd71 --- /dev/null +++ b/modules/cacsd/macros/cleanmacros.bat @@ -0,0 +1,3 @@ +@del *.bin 2>NUL +@del lib 2>NUL +@del names 2>NUL
\ No newline at end of file diff --git a/modules/cacsd/macros/cls2dls.bin b/modules/cacsd/macros/cls2dls.bin Binary files differnew file mode 100755 index 000000000..9f3109f5e --- /dev/null +++ b/modules/cacsd/macros/cls2dls.bin diff --git a/modules/cacsd/macros/cls2dls.sci b/modules/cacsd/macros/cls2dls.sci new file mode 100755 index 000000000..08fa16605 --- /dev/null +++ b/modules/cacsd/macros/cls2dls.sci @@ -0,0 +1,41 @@ +// 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 [s1]=cls2dls(s,t,fp) + //Syntax : s1=cls2dls(sl,t [,fp]) + // + // Given sl=[a,b,c,d] (syslin list) continuous time system, cls2dls + // returns the sampled system obatined by the bilinear transform + // s=(2/t)*(z-1)/(z+1). + // + // t sampling period + // fp prevarping frequency in hertz + //! + + [lhs,rhs]=argn(0) + if typeof(s)<>"state-space" + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"cls2dls",1)) + end + if s.dt==[] then + warning(msprintf(gettext("%s: Input argument %d is assumed continuous time.\n"),"cls2dls",1)); + s.dt="c"; + end + if s.dt<>"c" then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Continuous time system expected.\n"),"cls2dls",1)) + end + fs=1/t + if rhs==3 then fp=2*%pi*fp;fs=fp/tan(fp/fs/2)/2,end //prewarping + + a=2*fs*eye()-s(2) + ad=a\(2*fs*eye()+s(2)) + b=(ad+eye())/a*s(3); + d=s(5)+s(4)/a*s(3) + s1=syslin("d",ad,b,s(4),d,s(6)) +endfunction diff --git a/modules/cacsd/macros/colinout.bin b/modules/cacsd/macros/colinout.bin Binary files differnew file mode 100755 index 000000000..8ed17756c --- /dev/null +++ b/modules/cacsd/macros/colinout.bin diff --git a/modules/cacsd/macros/colinout.sci b/modules/cacsd/macros/colinout.sci new file mode 100755 index 000000000..1983e9024 --- /dev/null +++ b/modules/cacsd/macros/colinout.sci @@ -0,0 +1,14 @@ +// 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 [Inn,X,Gbar]=colinout(G) + + [Innt,Xt,Gbart]=rowinout(G'); + Inn=Innt';X=Xt';Gbar=Gbart'; +endfunction diff --git a/modules/cacsd/macros/colregul.bin b/modules/cacsd/macros/colregul.bin Binary files differnew file mode 100755 index 000000000..f5daae6ca --- /dev/null +++ b/modules/cacsd/macros/colregul.bin diff --git a/modules/cacsd/macros/colregul.sci b/modules/cacsd/macros/colregul.sci new file mode 100755 index 000000000..fa84ed132 --- /dev/null +++ b/modules/cacsd/macros/colregul.sci @@ -0,0 +1,73 @@ +// 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 [Stmp,Ws]=colregul(Sl,Alfa,Beta); + // [Stmp,Ws]=regul(Sl) computes a polynomial-state-space prefilter + // Ws such that Stmp=Sl*Ws is proper and non singular. + // Poles at infinity of Sl are moved to Alfa; + // Zeros at infinity of Sl are moved to Beta; + // Sl is asummed left invertible i.e. ss2tf(Sl) full column rank + //! + + [LHS,RHS]=argn(0); + if RHS==1 then Alfa=0;Beta=0;end + flag=0; + Sl1=Sl(1) + if Sl1(1)=="r" then + flag=1;Sl=tf2ss(Sl); + end + s=poly(0,"s"); + D=Sl(5); + n=size(D);n1=n(1);n2=n(2); + Ws=syslin([],[],[],[],eye(n2,n2)); + Stmp=Sl; + m=max(degree(D)); + // moving poles @ infinity to poles @ Alfa + while m>0 + Dm=coeff(D,m); + [W,r]=colcomp(Dm); + if r==0 then Wstmp=W; else + dim=n2-r;Wstmp=W*[eye(dim,dim),zeros(dim,r); + zeros(r,dim),tf2ss(1/(s-Alfa)*eye(r,r))];end + Ws=Ws*Wstmp; + Stmp=Stmp*Wstmp; + D=clean(Stmp(5)); + m=max(degree(D)); + end + Stmp(5)=coeff(Stmp(5),0); + + [W,r]=colcomp(Stmp(5)); + if r==n1 then + Ws=Ws*W;Stmp=Stmp*W; + if flag==1 then Ws=ss2tf(Ws);Stmp=ss2tf(Stmp);end + return; + end + [nx,nx]=size(Stmp(2)); + // moving zeros @ infinity to zeros @ Beta + i=0; + while r < n2, + i=i+1; + if r==n2 then Wstmp=W; + else + dim=n2-r;Wstmp=W*[(s-Beta)*eye(dim,dim),zeros(dim,r); + zeros(r,dim),eye(r,r)]; + end + Wstmp=syslin([],[],[],[],Wstmp); + Ws=Ws*Wstmp; + Stmp=Stmp*Wstmp; + Stmp(5)=coeff(Stmp(5),0); + rold=r; + [W,r]=colcomp(Stmp(5)); + // if r==rold&r<>0 then break;end + if i>=nx then break;end + end + if flag==1 then + Ws=ss2tf(Ws);Stmp=ss2tf(Stmp);end +endfunction diff --git a/modules/cacsd/macros/cont_frm.bin b/modules/cacsd/macros/cont_frm.bin Binary files differnew file mode 100755 index 000000000..22811908b --- /dev/null +++ b/modules/cacsd/macros/cont_frm.bin diff --git a/modules/cacsd/macros/cont_frm.sci b/modules/cacsd/macros/cont_frm.sci new file mode 100755 index 000000000..26148bf94 --- /dev/null +++ b/modules/cacsd/macros/cont_frm.sci @@ -0,0 +1,48 @@ +// 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 sl=cont_frm(num,den) + //Controllable state-space form of the transfer num/den + //! + [lhs,rhs]=argn(0) + if size(den,"*")<>1 then error(54,2);end + [ns,ne]=size(num); + if type(num)==1 then + if type(den)==1 then + sl=syslin([],[],[],[],num./den,[]) + return + else + num(1,1)=poly(num(1,1),varn(den),"c"), + end + end + nd=degree(den); + // normalization + dnd=coeff(den,nd);den=den/dnd;num=num/dnd + // D(s) + for l=1:ns, + for k=1:ne, + [nl,dl]=pdiv(num(l,k),den), + num(l,k)=nl,d(l,k)=dl, + end, + end + if max(degree(d))==0 then d=coeff(d),end + //matrices a b and c + if nd<>0 then + den=coeff(den);c=coeff(num,0:nd-1) + a=[]; + for k=1:nd,a=[a,-den(k)*eye(ne,ne)];end + a=[0*ones((nd-1)*ne,ne),eye(ne*(nd-1),ne*(nd-1));a]; + b=[0*ones((nd-1)*ne,ne);eye(ne,ne)] + else + a=[];b=[];c=[] + end; + [n,n]=size(a); + sl=syslin([],a,b,c,d,0*ones(n,1)) +endfunction diff --git a/modules/cacsd/macros/cont_mat.bin b/modules/cacsd/macros/cont_mat.bin Binary files differnew file mode 100755 index 000000000..2d3b36339 --- /dev/null +++ b/modules/cacsd/macros/cont_mat.bin diff --git a/modules/cacsd/macros/cont_mat.sci b/modules/cacsd/macros/cont_mat.sci new file mode 100755 index 000000000..918845cae --- /dev/null +++ b/modules/cacsd/macros/cont_mat.sci @@ -0,0 +1,42 @@ +// 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 c=cont_mat(a,b) + //c=cont_mat(a,b) or c=cont_mat(sl) is the controllability matrix. + // of the pair a,b or of the system sl=[a,b,c,d] (syslin list) + // 2 n + //i.e. c=[b, ab, ab,...; ab ] + //! + [lhs,rhs]=argn(0) + select typeof(a) + case "constant" then + if rhs==1 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected"),"cont_mat",2)), + end + [m,n]=size(a) + if m<>n then error(20,1),end + [mb,nb]=size(b); + if mb<>n then error(60),end + + case "state-space" then + if rhs==2 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected"),"cont_mat",1)), + end + [a,b]=a([2,3]) + [n,n]=size(a) + else + if rhs==1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear dynamical system expected.\n"),"cont_mat",1)) + else + error(msprintf(gettext("%s: Wrong type of input argument #%d: Array of floating point numbers expected.\n"),"cont_mat",1)) + end + + end; + c=b;for k=1:n-1, c=[b,a*c],end +endfunction diff --git a/modules/cacsd/macros/contrss.bin b/modules/cacsd/macros/contrss.bin Binary files differnew file mode 100755 index 000000000..c6bc26860 --- /dev/null +++ b/modules/cacsd/macros/contrss.bin diff --git a/modules/cacsd/macros/contrss.sci b/modules/cacsd/macros/contrss.sci new file mode 100755 index 000000000..985bf3dde --- /dev/null +++ b/modules/cacsd/macros/contrss.sci @@ -0,0 +1,25 @@ +// 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 slc=contrss(a,tol) + + [lhs,rhs]=argn(0) + // + if typeof(a)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: State-space form expected.\n"),"contrss",1)); + end + + if rhs==1 then tol=sqrt(%eps);end + [a,b,c,d,x0,dom]=a(2:7) + // + [nc,u]=contr(a,b,tol*norm([a,b],1)) + u=u(:,1:nc) + a=u'*a*u;b=u'*b;c=c*u + slc=syslin(dom,a,b,c,d,u'*x0) +endfunction diff --git a/modules/cacsd/macros/copfac.bin b/modules/cacsd/macros/copfac.bin Binary files differnew file mode 100755 index 000000000..fe534ec05 --- /dev/null +++ b/modules/cacsd/macros/copfac.bin diff --git a/modules/cacsd/macros/copfac.sci b/modules/cacsd/macros/copfac.sci new file mode 100755 index 000000000..23536ed7d --- /dev/null +++ b/modules/cacsd/macros/copfac.sci @@ -0,0 +1,101 @@ +// 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 [n,m,xt,yt]=copfac(g,polf,polc,tol) + //[n,m,xt,yt]=copfac(G,[polf,polc,[tol]]) returns a right coprime + //factorization of g : + // g = n*m^-1 where n and m are stable, proper and right coprime. + // (ie. [n m] left-invertible with stability) + // xt and yt satisfy: + // [xt -yt].[m n]' = eye (Bezout identity) + // G is assumed stabilizable and detectable. + //-- G is is linear system (syslin list) + //-- polf are polc respectively the poles of xt and yt + // and the poles of n and m . + // These are optional arguments with defautl values -1. + //-- tol is a threshold for detecting stable poles. + //! + + [lhs,rhs]=argn(0), + if rhs<1 then + error(msprintf(gettext("%s: Wrong number of input arguments: At least %d expected.\n"),"copfac",1)) + end + select typeof(g) + case "rational" then + g=tf2ss(g) + case "state-space" then + else + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"copfac",1)) + end + if g.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"copfac",1)) + end + + [r,p,t]=size(g); + [a,b,c,d]=abcd(g), + [n1,u1]=contr(a,b),[n2,u2]=contr(a',c'), + select rhs, + case 1 then + polc=-ones(1,n1),polf=-ones(1,n2),tol=1000*%eps, + case 2 then + itol=2 + tol=polf,polc=-ones(1,n1),polf=-ones(1,n2), + case 3 then + tol=1000*%eps, + else + itol=4 + end, + 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"),"copfac",itol)) + end + if type(polf)<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Vector of floats expected.\n"),"copfac",2)) + end + if size(polf,"*")<>n2 then + error(msprintf(gettext( "%s: Wrong size for argument #%d: %d expected.\n"),"copfac",2,n2)) + end + if type(polc)<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Vector of floats expected.\n"),"copfac",3)) + end + if size(polc,"*")<>n1 then + error(msprintf(gettext( "%s: Wrong size for argument #%d: %d expected.\n"),"copfac",3,n1)) + end + + + //-------------------- + if n1<>t then + w1=u1(:,n1+1:t),a1=w1'*a*w1, + no=norm(a1), + if max(real(spec(a1)))>no*tol then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Stabilizable system expected.\n"),"copfac",1)), + end, + end, + //------------------ + if n2<>t then + w2=u2(:,n2+1:t),a2=w2'*a*w2, + no=norm(a2), + if max(real(spec(a2)))>no*tol then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Detectable system expected.\n"),"copfac",1)), + end, + end, + //----------------------------- + v1=u1(:,1:n1),a1=v1'*a*v1,b1=v1'*b, + k1=ppol(a1,b1,polc)*v1', + ak1=a-b*k1,ck1=c-d*k1, + v2=u2(:,1:n2),a2=v2'*a*v2,c2=c*v2, + k2=ppol(a2',c2',polf), + k2=v2*k2', + ak2=a-k2*c,bk2=b-k2*d, + //------------------- + m=syslin("c",ak1,b,-k1,eye(p,p)), + n=syslin("c",ak1,b,ck1,d), + xt=syslin("c",ak2,-bk2,-k1,eye(p,p)), + yt=syslin("c",ak2,k2,-k1), +endfunction diff --git a/modules/cacsd/macros/csim.bin b/modules/cacsd/macros/csim.bin Binary files differnew file mode 100755 index 000000000..99a31331a --- /dev/null +++ b/modules/cacsd/macros/csim.bin diff --git a/modules/cacsd/macros/csim.sci b/modules/cacsd/macros/csim.sci new file mode 100755 index 000000000..d14fe4e3e --- /dev/null +++ b/modules/cacsd/macros/csim.sci @@ -0,0 +1,165 @@ +// 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 [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 + //! + + [lhs,rhs]=argn(0) + // + if rhs<3 then error(39),end + sltyp=typeof(sl) + if and(sltyp<>["state-space" "rational"]) then + error(msprintf(_("%s: Wrong type for input argument #%d: %s data structure expected.\n"),"csim",3,"syslin")) + end + if sltyp=="rational" then sl=tf2ss(sl),end + if sl.dt<>"c" then + warning(msprintf(gettext("%s: Input argument #%d is assumed continuous time.\n"),"csim",1)); + end + // + [a,b,c,d]=sl(2:5); + if degree(d)>0 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A proper system expected\n"),"csim",1)); + end + [ma,mb]=size(b); + // + imp=0;step=0 + text="if t==0 then y=0, else y=1,end" + // + select type(u) + case 10 then //input given by its type (step or impuls) + if mb<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A SIMO expected.\n"),"csim",1)); + end; + if part(u,1)=="i" then + //impulse response + imp=1; + dt(dt==0)=%eps^2; + elseif part(u,1)=="s" then + step=1 + if norm(d,1)<>0 then + dt(dt==0)=%eps^2; + end; + else + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),"csim",1,"""step"",""impuls""")) + end; + deff("[y]=u(t)",text); + case 11 then //input given by a function of time + comp(u) + case 13 then //input given by a function of time + case 1 then //input given by a vector of data + [mbu,ntu]=size(u); + if mbu<>mb | ntu<>size(dt,"*") then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),"csim",1,2)) + end + case 15 then //input given by a list: function of time with parameters + 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|step==1 then x0=0*x0,end + nt=size(dt,"*");x=0*ones(ma,nt); + [a,v]=balanc(a); + v1=v;//save for backward transformation + + //apply transformation u without matrix inversion + [k,l]=find(v<>0) //get the permutation + + //apply right transformation + v=v(k,l);//diagonal matrix + c=c(:,k)*v; + //apply left transformation + v=diag(1 ./diag(v));b=v*b(k,:);x0=v*x0(k) + + [a,v2,bs]=bdiag(a,1);b=v2\b;c=c*v2;x0=v2\x0; + //form the differential equation function + if type(u)==1 then + //form a continuous time interpolation of the given data + 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=max([norm(bk*ut,1),norm(x0(kk))]); + if nrmu > 0 then + if rhs<5 then + atol=1.d-12*nrmu;rtol=atol/100; + else + atol=tol(1);rtol=tol(2); + end + xkk=ode("adams",x0(kk),0,dt,rtol,atol,%sim2); + if size(xkk,2)<>size(x,2) then + error(msprintf(_("%s: Simulation failed before final time is reached.\n"),"csim")) + end + x(kk,:)=xkk; + if imp==1 then x(kk,:)=ak*x(kk,:)+bk*ut,end + end; + k=k+n + end; + y=c*x+d*ut + if lhs==2 then x=v1*v2*x,end +endfunction diff --git a/modules/cacsd/macros/ctr_gram.bin b/modules/cacsd/macros/ctr_gram.bin Binary files differnew file mode 100755 index 000000000..ffa461f51 --- /dev/null +++ b/modules/cacsd/macros/ctr_gram.bin diff --git a/modules/cacsd/macros/ctr_gram.sci b/modules/cacsd/macros/ctr_gram.sci new file mode 100755 index 000000000..7d320d200 --- /dev/null +++ b/modules/cacsd/macros/ctr_gram.sci @@ -0,0 +1,65 @@ +// 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 [gc]=ctr_gram(a,b,domaine) + //! + + [lhs,rhs]=argn(0) + select typeof(a) + case "constant" then + if rhs<2 then error(39); end; + if rhs==2 then + domaine="c"; + else + if and(domaine<>["d","c"]) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"), "ctr_gram",3,"''d'', ''c''")); + end + end; + [m,n]=size(a) + if m<>n then error(20,1),end + [mb,nb]=size(b);if mb<>n then error(60),end + case "state-space" then + if rhs>1 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected"),"ctr_gram",1)), + end + [a,b,domaine]=a([2,3,7]) + if domaine==[] then + warning(msprintf(gettext("%s: Input argument %d is assumed continuous time.\n"),"ctr_gram",1)); + domaine="c"; + elseif type(domaine)==1 then + domaine="d", + end + [n,n]=size(a) + case "rational" then + if rhs>1 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected"),"ctr_gram",1)), + end + a=tf2ss(a) + [a,b,domaine]=a([2,3,7]) + if domaine==[] then + warning(msprintf(gettext("%s: Input argument %d is assumed continuous time.\n"),"ctr_gram",1)); + domaine="c"; + elseif type(domaine)==1 then + domaine="d", + end + [n,n]=size(a) + else + if rhs==1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear dynamical system expected.\n"),"ctr_gram",1)) + else + error(msprintf(gettext("%s: Wrong type of input argument #%d: Array of floating point numbers expected.\n"),"ctr_gram",1)) + end + end + s=spec(a) + if (domaine=="c"&max(real(s))>=0)|(domaine=="d"&max(abs(s))>=1) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Stable system expected.\n"),"ctr_gram",1)); + end + gc=lyap(a',-b*b',domaine) +endfunction diff --git a/modules/cacsd/macros/damp.bin b/modules/cacsd/macros/damp.bin Binary files differnew file mode 100755 index 000000000..1ea78ffdc --- /dev/null +++ b/modules/cacsd/macros/damp.bin diff --git a/modules/cacsd/macros/damp.sci b/modules/cacsd/macros/damp.sci new file mode 100755 index 000000000..435256255 --- /dev/null +++ b/modules/cacsd/macros/damp.sci @@ -0,0 +1,97 @@ +function [wn,z,p] = damp(R,dt1) + //Natural frequency and damping factor for continuous systems. + // [Wn,Z,P] = damp(R) returns vectors Wn and Z containing the + // natural frequencies and damping factors of R. + // The variable R must be a real or complex array of roots, a + // polynomial array or a linear dynamical system + + if argn(2)<1 then + error(msprintf(_("%s: Wrong number of input arguments: %d or %d expected.\n"),"damp",1,2)) + end + //handling optional argument dt1 + if argn(2)==1 then + dt1=[]; + else + if type(dt1)==1 then + if size(dt1,"*")<>1|dt1<0 then + error(msprintf(_("%s: Wrong type for input argument #%d: Real non negative scalar expected.\n"),.. + "damp",2)) + end + elseif type(dt1)==10 then + if dt1=="c" then + dt1=0 + elseif dt1=="d" then + dt1=1 + else + error(msprintf(_("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),.. + "damp",2,"""c"", ""d""")) + end + else + error(msprintf(_("%s: Wrong type for input argument #%d: Scalar or string expected.\n"),.. + "damp",2)) + end + end + + toBeOrdered=%t;dt=[]; + select typeof(R) + case "polynomial" then //polynomial array + p=[]; + for k=1:size(R,"*") + p=[p;roots(R(k),"e")]; + end + case "rational" then + dt=R.dt + if dt=="c" then + dt=0 + elseif dt=="d" then + dt=1 + end + p=roots(lcm(R.den)) + case "state-space" then + dt=R.dt + if dt=="c" then + dt=0 + elseif dt=="d" then + dt=1 + end + p=spec(R.A) + case "constant" then + p=R; + toBeOrdered=%f + else + error(msprintf(_("%s: Wrong type for input argument #%d: Array of floats or Polynomial expected.\n"),.. + "damp",1)) + end + if dt==[] then + //R does not furnish time domain + if dt1==[] then + //no user time domain specified, continuuous time assumed + dt=0 + else + //user time domain specified + dt=dt1 + end + elseif dt1<>[] then + warning(msprintf(_("%s: Input argument #%d ignored.\n"),"damp",2)) + end + // Initialize + wn=zeros(p); + z=-ones(p); + im=ieee();ieee(2);//to allow inf and nan's + if dt>0 then // Discrete time case + ind=find(p<>1) + s=p(ind); + s=log(s)/dt; + else //continuous time case + ind=find(p<>0) + s=p(ind); + end + wn(ind)=abs(s) + z(ind)=-real(s)./abs(s) + ieee(im) + if toBeOrdered then + [wn,k]=gsort(wn,"g","i"); + z=z(k); + p=p(k) + end +endfunction diff --git a/modules/cacsd/macros/dbphi.bin b/modules/cacsd/macros/dbphi.bin Binary files differnew file mode 100755 index 000000000..4bbd8800f --- /dev/null +++ b/modules/cacsd/macros/dbphi.bin diff --git a/modules/cacsd/macros/dbphi.sci b/modules/cacsd/macros/dbphi.sci new file mode 100755 index 000000000..154029299 --- /dev/null +++ b/modules/cacsd/macros/dbphi.sci @@ -0,0 +1,17 @@ +// 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 [db,phi]=dbphi(repf,mod) + + [lhs,rhs]=argn(0) + if rhs==1 then mod="c",end + phi=phasemag(repf,mod); + db=20*log(abs(repf))/log(10); +endfunction diff --git a/modules/cacsd/macros/dcf.bin b/modules/cacsd/macros/dcf.bin Binary files differnew file mode 100755 index 000000000..4b8eccc6f --- /dev/null +++ b/modules/cacsd/macros/dcf.bin diff --git a/modules/cacsd/macros/dcf.sci b/modules/cacsd/macros/dcf.sci new file mode 100755 index 000000000..5c607c3e3 --- /dev/null +++ b/modules/cacsd/macros/dcf.sci @@ -0,0 +1,34 @@ +// 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 [n,m,x,y,nt,mt,xt,yt]=dcf(g,polf,polc,tol) + //[n,m,x,y,nt,mt,xt,yt]=dcf(g,[polf,polc,[tol]]) returns eight + //stable systems (n,m,x,y,nt,mt,xt,yt) for the doubly coprime factorization + // + // !xt -yt! ! m y ! + // ! !*! ! = eye + // !-nt mt! ! n x ! + // G must be stabilizable and detectable. + // See copfac for a description of parameters. + //! + + [lhs,rhs]=argn(0), + n1=contr(g(2),g(3)),n2=contr(g(2)',g(4)'), + select rhs, + case 1 then + polc=-ones(1,n1),polf=-ones(1,n2),tol=1000*%eps, + case 2 then + tol=polf,polc=-ones(1,n1),polf=-ones(1,n2), + case 3 then tol=1000*%eps, + end, + [n,m,xt,yt]=copfac(g,polf,polc,tol), + [nt,mt,x,y]=copfac(g',polc,polf,tol), + nt=nt',mt=mt',x=x',y=y', +endfunction diff --git a/modules/cacsd/macros/ddp.bin b/modules/cacsd/macros/ddp.bin Binary files differnew file mode 100755 index 000000000..edf35900e --- /dev/null +++ b/modules/cacsd/macros/ddp.bin diff --git a/modules/cacsd/macros/ddp.sci b/modules/cacsd/macros/ddp.sci new file mode 100755 index 000000000..3e8f7de4b --- /dev/null +++ b/modules/cacsd/macros/ddp.sci @@ -0,0 +1,96 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [Closed,F,G]=ddp(Sys,zeroed,B1,D1,flag,Alfa,Beta) + //--------------Exact disturbance decoupling---------- + // Given a linear system, and a subset of outputs, z, which are to + // be zeroed, characterize the inputs w of Sys such that the + // transfer function from w to z is zero. + // + // Sys = linear system {A,B2,C,D2} with one input and two outputs + // i.e Sys: u-->(z,y) in the following + // + // xdot = A x + B1 w + B2 u + // z = C1 x + D11 w + D12 u + // y = C2 x + D21 w + D22 u + // + // outputs of Sys are partitioned into (z,y) where z is to be zeroed, + // i.e. the matrices C and D2 are: + // + // C=[C1;C2] D2=[D12;D22] + // C1=C(zeroed,:) D12=D1(zeroed,:) + // + // The control is u=Fx+Gw and one + // looks for F,G such that the closed loop system: w-->z given by + // + // xdot= (A+B2*F) x + (B1 + B2*G) w + // z = (C1+D12F) x + (D11+D12*G) w + // + // has zero transfer transfer function. + // + // flag='ge' : no stability constraints + // ='st' : look for stable closed loop system (A+B2*F stable) + // ='pp' : eigenvalues of A+B2*F are assigned to Alfa and Beta + // + // Closed = w-->y closed loop system + // + // xdot= (A+B2*F) x + (B1 + B2*G) w + // y = (C2+D22*F) x + (D21+D22*G) w + // + // Stability (resp. pole placement) requires stabilizability + // (resp. controllability) of (A,B2). + // + [LHS,RHS]=argn(0); + if RHS==5 then Beta=-1;end + if RHS==4 then Beta=-1;Alfa=-1;end + if RHS==3 then Beta=-1;Alfa=-1;flag="st";end + if RHS==2 then Beta=-1;Alfa=-1;flag="st";D1=zeros(size(Sys("C"),1),size(B1,2)); + end + if size(B1,1) ~= size(Sys("A"),1) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same row dimensions expected.\n"),"ddp",1,3)) + end + if size(D1,2) ~= size(B1,2) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same row dimensions expected.\n"),"ddp",3,4)) + end + Sys1=Sys(zeroed,:); + not_zeroed=1:size(Sys,1);not_zeroed(zeroed)=[]; + [X,dims,F,U,k,Z]=abinv(Sys1,Alfa,Beta,flag);nv=dims(3); + Sys_new=ss2ss(Sys,X);Fnew=F*X; + B1new=X'*B1;B2new=Sys_new("B"); + D11=D1(zeroed,:);D12=Sys1("D"); + B21=B1new(nv+1:$,:);B22=B2new(nv+1:$,:); + // G s.t. B21+B22*G=0 D11+D12*G=0 + G=lowlev(); + + [Anew,Bnew,Cnew,Dnew]=abcd(Sys_new); + Anew=Anew+B2new*Fnew;Cnew=Cnew+Dnew*Fnew; + B1new=B1new+B2new*G; + A11=Anew(1:nv,1:nv);C21=Cnew(not_zeroed,1:nv); + B11=B1new(1:nv,:);D21=D1(not_zeroed,:); + D22=Sys("D");D22=D22(not_zeroed,:);D21=D21+D22*G; + Closed=syslin(Sys("dt"),A11,B11,C21,D21); + + +endfunction + +function G=lowlev() + ww=[B21 B22;D11 D12]; + [xx,dd]=colcomp(ww); + K=kernel(ww); + rowG=size(B22,2);colG=size(B1,2); + if size(K,2) > colG then K=K(:,1:colG);end + Kup=K(1:size(K,2),:); + if rcond(Kup) <= 1.d-10 then + warning(msprintf(gettext("%s: Bad conditioning.\n"),"ddp")); + K1=K*pinv(Kup);G=K1(size(K,2)+1:$,:);return + end + K1=K*inv(Kup); //test conditioning here! + G=K1(size(K,2)+1:$,:); +endfunction diff --git a/modules/cacsd/macros/des2ss.bin b/modules/cacsd/macros/des2ss.bin Binary files differnew file mode 100755 index 000000000..979b14644 --- /dev/null +++ b/modules/cacsd/macros/des2ss.bin diff --git a/modules/cacsd/macros/des2ss.sci b/modules/cacsd/macros/des2ss.sci new file mode 100755 index 000000000..fed1f619e --- /dev/null +++ b/modules/cacsd/macros/des2ss.sci @@ -0,0 +1,56 @@ +// 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 [s1]=des2ss(a,b,c,d,e,tol) + //descriptor to state-space + //! + + [lhs,rhs]=argn(0) + if rhs==1 then + [a,b,c,d,e]=a(2:6); + // if norm(d,1)<>0 then warning('des2ss: d matrix must be zero!');end + [bfs,bis,chis]=glever(e,a); + s1=c*tf2ss(bfs/chis)*b;s1(5)=-c*bis*b+d; + return; + end + if rhs == 5 then tol=1.e-8;end + [ns,ns] = size(a); + if norm(e,1) < %eps then s1=syslin([],[],[],[],-c/a*b + d);return;end + [ue,se,ve,rk] = svd(e,tol*norm(e,1)); + k=ns-rk; + if k==0 then ei=inv(e),s1=syslin([],ei*a,ei*b,c,d),return,end + u1=ue(:,1:ns-k); u2=ue(:,ns-k+1:ns); + v1=ve(:,1:ns-k); v2=ve(:,ns-k+1:ns); + if k==0 then u2=1,v2=1;end + a22=u2'*a*v2; + if rcond(a22) < 1.d-4 then + // higher index... + s=poly(0,"s");[ws,fs1]=rowshuff(s*e-a); + ww=inv(syslin("c",[],[],[],fs1)); + s1=c*ww*ws*b+d; + return + end + sei=sqrtm(inv(se(1:ns-k,1:ns-k))); + //sei=(se(1:ns-k,1:ns-k))^(-0.5) + a11=u1'*a*v1; + a12=u1'*a*v2; + a21=u2'*a*v1; + // index one... + a22i=inv(a22); + bb1 = u1'*b; + bb2 = u2'*b; + cc1 = c*v1; + cc2 = c*v2; + aa = sei * (a11 - a12*a22i*a21) * sei; + bb = sei * (bb1 - a12*a22i*bb2); + cc = (cc1 - cc2 * a22i * a21) * sei; + dd = d - cc2 * a22i * bb2; + s1=syslin([],aa,bb,cc,dd); +endfunction diff --git a/modules/cacsd/macros/des2tf.bin b/modules/cacsd/macros/des2tf.bin Binary files differnew file mode 100755 index 000000000..c26b2c7a0 --- /dev/null +++ b/modules/cacsd/macros/des2tf.bin diff --git a/modules/cacsd/macros/des2tf.sci b/modules/cacsd/macros/des2tf.sci new file mode 100755 index 000000000..3154aba89 --- /dev/null +++ b/modules/cacsd/macros/des2tf.sci @@ -0,0 +1,22 @@ +// 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 [Bfs,Bis,tf]=des2tf(des) + //des admits a D matrix. + + [LHS,RHS]=argn(0); + if LHS<>1 & LHS<> 3 then + error(msprintf(gettext("%s: Wrong number of output arguments: %d or %d expected.\n"), "des2tf",1,3)); + end + [A,B,C,D,E]=des(2:6); + [Bfs,Bis,chis]=glever(E,A); + if LHS==3 then Bfs=C*Bfs*B; Bis=C*Bis*B+D;tf=chis;return;end + if LHS==1 then ww=C*Bfs*B;Bfs=ww/chis-C*Bis*B+D;return;end +endfunction diff --git a/modules/cacsd/macros/dhnorm.bin b/modules/cacsd/macros/dhnorm.bin Binary files differnew file mode 100755 index 000000000..057af51e1 --- /dev/null +++ b/modules/cacsd/macros/dhnorm.bin diff --git a/modules/cacsd/macros/dhnorm.sci b/modules/cacsd/macros/dhnorm.sci new file mode 100755 index 000000000..95f2ea667 --- /dev/null +++ b/modules/cacsd/macros/dhnorm.sci @@ -0,0 +1,54 @@ +// 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 gama=dhnorm(Sl,tol,gamamax) + //discrete-time case + // included in h_norm! + [lhs,rhs]=argn(0); + if rhs==1 then tol=0.000001;gamamax=10000000;end + if rhs==2 then gamamax=1000;end + gamamin=sqrt(%eps); + n=0; + while %T + gama=(gamamin+gamamax)/2;n=n+1; + if n>1000 then warning(msprintf(gettext("%s: More than %d iterations.\n"),"dhnorm",1000));return;end + if dhtest(Sl,gama) then + gamamax=gama; else gamamin=gama + end + if (gamamax-gamamin)<tol then return;end + end + +endfunction +function ok=dhtest(Sl,gama) + //test if discrete hinfinity norm of Sl is < gama + [A,B,C,D]=Sl(2:5);B=B/sqrt(gama);C=C/sqrt(gama);D=D/gama; + R=eye()-D'*D; + [n,n]=size(A);Id=eye(n,n);Z=0*Id; + Ak=A+B*inv(R)*D'*C; + e=[Id,-B*inv(R)*B';Z,Ak']; + Aa=[Ak,Z;-C'*inv(eye()-D*D')*C,Id]; + [As,Es,w,k]=schur(Aa,e,"d"); + //Testing magnitude 1 eigenvalues. + [al,be]=spec(As,Es); + finite=find(abs(be)>0.00000001); + finite_eigen=al(finite)./be(finite); + bad=find( abs(abs(finite_eigen)-1) < 0.0000001); + if bad<>[] then ok=%f;return;end + //if k<>n then ok=%f;return;end + ws=w(:,1:n); + x12=ws(1:n,:); + phi12=ws(n+1:2*n,:); + if rcond(x12) > 1.d-6 then + X=phi12/x12; + z=eye()-B'*X*B + ok= min(real(spec(z))) > -%eps + else + ok=%t;end +endfunction diff --git a/modules/cacsd/macros/dscr.bin b/modules/cacsd/macros/dscr.bin Binary files differnew file mode 100755 index 000000000..12229abf1 --- /dev/null +++ b/modules/cacsd/macros/dscr.bin diff --git a/modules/cacsd/macros/dscr.sci b/modules/cacsd/macros/dscr.sci new file mode 100755 index 000000000..ce3e4e879 --- /dev/null +++ b/modules/cacsd/macros/dscr.sci @@ -0,0 +1,48 @@ +// 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 [f,r]=dscr(a,dt,m) + + [lhs,rhs]=argn(0); + if type(dt)<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real expected.\n"),"dscr",2)) + end + if size(dt,"*")<>1 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A scalar expected.\n"),"dscr",2)) + end + if ~isreal(dt) then + error(msprintf(gettext("%s: Input argument #%d must be real.\n"),"dscr",2)) + end + + if dt<=0 then + error(msprintf(gettext("%s: Input argument #%d must be strictly positive.\n"),"dscr",2)) + end + + select typeof(a) + case "rational" then + a=tf2ss(a); + [a,b,c,d,x0,dom]=a(2:7); + case "state-space" then + [a,b,c,d,x0,dom]=a(2:7) + else + error(97,1), + end; + if dom<>"c" then + warning(msprintf(gettext("%s: Input argument %d is assumed continuous time.\n"),"dscr",1)) + end + [n1,m1]=size(b), + s=expm([a,b;0*ones(m1,n1+m1)]*dt), + f=s(1:n1,1:n1);g=s(1:n1,n1+1:n1+m1); + if rhs==3 then + s=expm([-a,m;0*a a']*dt), + r=f*s(1:n1,n1+1:n1+n1), + end; + f=syslin(dt,f,g,c,d,x0) +endfunction diff --git a/modules/cacsd/macros/dsimul.bin b/modules/cacsd/macros/dsimul.bin Binary files differnew file mode 100755 index 000000000..7d7abe973 --- /dev/null +++ b/modules/cacsd/macros/dsimul.bin diff --git a/modules/cacsd/macros/dsimul.sci b/modules/cacsd/macros/dsimul.sci new file mode 100755 index 000000000..4eb3cfd36 --- /dev/null +++ b/modules/cacsd/macros/dsimul.sci @@ -0,0 +1,15 @@ +// 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 [y]=dsimul(sld,u) + + [a,b,c,d,x0]=sld(2:6); + y=c*ltitr(a,b,u,x0)+d*u; +endfunction diff --git a/modules/cacsd/macros/dt_ility.bin b/modules/cacsd/macros/dt_ility.bin Binary files differnew file mode 100755 index 000000000..430ebd5b7 --- /dev/null +++ b/modules/cacsd/macros/dt_ility.bin diff --git a/modules/cacsd/macros/dt_ility.sci b/modules/cacsd/macros/dt_ility.sci new file mode 100755 index 000000000..0768ad819 --- /dev/null +++ b/modules/cacsd/macros/dt_ility.sci @@ -0,0 +1,29 @@ +// 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 [m1,m2,u2,sl2]=dt_ility(sl,tol) + //dual of st_ility + //detectability means m1=0; + //m1=dimension of unstable,unobservable subspace + //m2=dimension of unobservable subspace; m2>=m1 + //sl2=ss2ss(sl,u2) + //! + + [LHS,RHS]=argn(0) + if RHS==2 then + [n1,n2,u1,sl1]=st_ility(sl',tol); + else + [n1,n2,u1,sl1]=st_ility(sl'); + end + [nx,nx]=size(sl(2)); + u2=[u1(:,n1+1:nx),u1(:,n2+1:n1),u1(:,1:n2)]; + sl2=ss2ss(sl,u2); + m1=nx-n1;m2=nx-n2; +endfunction diff --git a/modules/cacsd/macros/dtsi.bin b/modules/cacsd/macros/dtsi.bin Binary files differnew file mode 100755 index 000000000..a779f8cce --- /dev/null +++ b/modules/cacsd/macros/dtsi.bin 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 diff --git a/modules/cacsd/macros/entropy.bin b/modules/cacsd/macros/entropy.bin Binary files differnew file mode 100755 index 000000000..b92d02685 --- /dev/null +++ b/modules/cacsd/macros/entropy.bin diff --git a/modules/cacsd/macros/entropy.sci b/modules/cacsd/macros/entropy.sci new file mode 100755 index 000000000..d2d37f6bb --- /dev/null +++ b/modules/cacsd/macros/entropy.sci @@ -0,0 +1,27 @@ +// 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 [enx,X,Y,eny]=entropy(S,gama) + //Computation of the entropy at gama of a linear system S + //[enx,X,Y,eny]=entropy(S,gama) + //! + // + + S1=S(1); + if S1(1)=="r" then S=tf2ss(S);end + [A,B,C,D]=S(2:5); + g1=1/gama; + H=[A,g1*B*B';-g1*C'*C,-A']; + [X,zero]=ric_desc(H); //zero=A'*X+X*A+g1*g1*X*B*B'*X+C'*C; + enx=sum(diag(X*B*B')); + J=[A',g1*C'*C;-g1*B*B',-A]; + [Y,zero]=ric_desc(J); //zero=A*Y+Y*A'+g1*g1*Y*C'*C*Y+B*B' + eny=sum(diag(Y*C'*C)); +endfunction diff --git a/modules/cacsd/macros/epred.bin b/modules/cacsd/macros/epred.bin Binary files differnew file mode 100755 index 000000000..7488eeedf --- /dev/null +++ b/modules/cacsd/macros/epred.bin diff --git a/modules/cacsd/macros/epred.sci b/modules/cacsd/macros/epred.sci new file mode 100755 index 000000000..1ae918bff --- /dev/null +++ b/modules/cacsd/macros/epred.sci @@ -0,0 +1,35 @@ +// 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 [sig,resid]=epred(r,s,q,coef,y,u,b0f) + //<sig,resid>=epred(r,s,q,coef,y,u,b0f) + // Utilisee par armax1 pour calculer l'erreur de prediction + // coef= [-a1,..,-ar,b0,...,b_s,d1,...,d_q]' + // ou coef= [-a1,..,-ar,b1,...,b_s,d1,...,d_q]' si b0f=1 + //! + + [n1,n2]=size(y); + t0=max(max(r,s+1),1)+1; + if r<>0;XTM1=y((t0-1):-1:(t0-r));else XTM1=[];end + if s<>-1;UTM1=u(t0-b0f:-1:(t0-s));else UTM1=[];end + if q<>0;ETM1=0*ones(1,q);else ETM1=[];end + npar=r+s+1-b0f+q + ZTM1=[XTM1,UTM1,ETM1]'; + resid=0*ones(1,n2); + for t=t0+1:n2, + if r<>0;XT=[ y(t-1), XTM1(1:(r-1))];else XT=[];end + if s<>-1;UT=[ u(t-b0f), UTM1(1:(s-b0f))];else UT=[];end + resid(t)=y(t-1)- coef'*ZTM1; + if q<>0;ET=[ resid(t), ETM1(1:(q-1))];else ET=[];end + ZT=[XT,UT,ET]'; + XTM1=XT;UTM1=UT;ETM1=ET;ZTM1=ZT; + end + sig=1/(n2-t0)*sum(resid.*resid) +endfunction diff --git a/modules/cacsd/macros/equil.bin b/modules/cacsd/macros/equil.bin Binary files differnew file mode 100755 index 000000000..cc7bfd971 --- /dev/null +++ b/modules/cacsd/macros/equil.bin diff --git a/modules/cacsd/macros/equil.sci b/modules/cacsd/macros/equil.sci new file mode 100755 index 000000000..e5b72426e --- /dev/null +++ b/modules/cacsd/macros/equil.sci @@ -0,0 +1,18 @@ +// 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 [t]=equil(p,q) + + t=chol(q); + [u,s,u]=svd(t*p*t'); + s=diag(s); + ll=ones(s)./sqrt(sqrt(s)); + t=diag(ll)*u'*t +endfunction diff --git a/modules/cacsd/macros/equil1.bin b/modules/cacsd/macros/equil1.bin Binary files differnew file mode 100755 index 000000000..b0fb5c673 --- /dev/null +++ b/modules/cacsd/macros/equil1.bin diff --git a/modules/cacsd/macros/equil1.sci b/modules/cacsd/macros/equil1.sci new file mode 100755 index 000000000..840784183 --- /dev/null +++ b/modules/cacsd/macros/equil1.sci @@ -0,0 +1,55 @@ +// 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 [t,siz]=equil1(p,q,tol) + // + + [n,n]=size(p); + [lhs,rhs]=argn(0); + // t1 + if rhs==2 then + [u,p,u,np]=svd(p); + else + [u,p,u,np]=svd(p,tol); + end; + p=sqrt(diag(p));p=[p(1:np);ones(n-np,1)]; + t1=diag(ones(n,1)./p)*u'; + // + // t2 + q=diag(p)*(u'*q*u)*diag(p) // q1=t1**-1'*q*t1**-1 + if rhs==2 then + [u,sigma1,u,nq]=svd(q(1:np,1:np)) + else + [u,sigma1,u,nq]=svd(q(1:np,1:np),tol) + end; + sigma1=sqrt(diag(sigma1(1:nq,1:nq))) + t2=[u',0*ones(np,n-np);0*ones(n-np,np) eye(n-np,n-np)]; + // + // t3 + q=t2*q*t2';t3=eye(n,n); + if np<>n then + x=diag(ones(nq,1)./(sigma1.*sigma1))*q(1:nq,np+1:n) + t3(1:nq,np+1:n)=-x; + q=t3'*q*t3;// here t3 value is in reality t3**-1 + t3(1:nq,np+1:n)=x; + end; + // + // t4 + if rhs==2 then + [u,q,u,n3]=svd(q(np+1:n,np+1:n)); + else + [u,q,u,n3]=svd(q(np+1:n,np+1:n),tol); + end; + t4=[diag(sqrt(sigma1)) 0*ones(nq,n-nq); + 0*ones(np-nq,nq) eye(np-nq,np-nq) 0*ones(np-nq,n-np); + 0*ones(n-np,np) u'] + t=t4*t3*t2*t1 + siz=[nq,np-nq,n3] +endfunction diff --git a/modules/cacsd/macros/evans.bin b/modules/cacsd/macros/evans.bin Binary files differnew file mode 100755 index 000000000..a69356fb3 --- /dev/null +++ b/modules/cacsd/macros/evans.bin diff --git a/modules/cacsd/macros/evans.sci b/modules/cacsd/macros/evans.sci new file mode 100755 index 000000000..ab667bcdb --- /dev/null +++ b/modules/cacsd/macros/evans.sci @@ -0,0 +1,228 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 evans(n,d,kmax) + // Seuil maxi et mini (relatifs) de discretisation en espace + // Copyright INRIA + + smax=0.002;smin=smax/3; + nptmax=2000 //nbre maxi de pt de discretisation en k + + //Check calling sequence + + [lhs,rhs]=argn(0) + + if rhs <= 0 then // demonstration + n=real(poly([0.1-%i 0.1+%i,-10],"s")); + d=real(poly([-1 -2 -%i %i],"s")); + evans(n,d,80); + return + end + + select typeof(n) + case "polynomial" then + if rhs==2 then kmax=0,end + case "rational" then + if rhs==2 then kmax=d,else kmax=0,end + [n,d]=n(2:3) + case "state-space" then + if rhs==2 then kmax=d,else kmax=0,end + n=ss2tf(n); + [n,d]=n(2:3);n=clean(n);d=clean(d); + else + error(msprintf(_("%s: Wrong type for input argument #%d: A linear dynamical system or a polynomial expected.\n"),"evans",1)); + end + if prod(size(n))<>1 then + error(msprintf(_("%s: Wrong value for input argument #%d: Single input, single output system expected.\n"),"evans",1)); + end + if degree(n)==0°ree(d)==0 then + error(msprintf(_("%s: The given system has no poles and no zeros.\n"),"evans")); + end + + if kmax<=0 then + nm=min([degree(n),degree(d)]) + fact=norm(coeff(d),2)/norm(coeff(n),2) + kmax=round(500*fact), + end + // + //Compute the discretization for "k" and the associated roots + nroots=roots(n);racines=roots(d); + if nroots==[] then + nrm=max([norm(racines,1),norm(roots(d+kmax*n),1)]) + else + nrm=max([norm(racines,1),norm(nroots,1),norm(roots(d+kmax*n),1)]) + end + md=degree(d) + // + ord=1:md;kk=0;nr=1;k=0;pas=0.99;fin="no"; + klim=gsort(krac2(rlist(n,d,"c")),"g","i") + ilim=1 + while fin=="no" then + k=k+pas + r=roots(d+k*n);r=r(ord) + dist=max(abs(racines(:,nr)-r))/nrm + // + point=%f + + if dist <smax then //pas correct + if k-pas<klim(ilim)& k>klim(ilim) then, + k=klim(ilim); + r=roots(d+k*n);r=r(ord) + end + if k>klim(ilim) then ilim=min(ilim+1,size(klim,"*"));end + point=%t + else //Too big step or incorrect root order + // look for a root order that minimize the distance + ix=1:md + ord1=[] + for ky=1:md + yy=r(ky) + mn=10*dist*nrm + for kx=1:md + if ix(kx)>0 then + if abs(yy-racines(kx,nr)) < mn then + mn=abs(yy-racines(kx,nr)) + kmn=kx + end + end + end + ix(kmn)=0 + ord1=[ord1 kmn] + end + r(ord1)=r + dist=max(abs(racines(:,nr)-r))/nrm + if dist <smax then + point=%t, + ord(ord1)=ord + else + k=k-pas,pas=pas/2.5 + end + end + if dist<smin then + //KToo small step + pas=2*pas; + end + if point then + racines=[racines,r];kk=[kk,k];nr=nr+1 + if k>kmax then fin="kmax",end + if nr>nptmax then fin="nptmax",end + end + end + //draw the axis + x1 =[nroots;matrix(racines,md*nr,1)]; + xmin=min(real(x1));xmax=max(real(x1)) + ymin=min(imag(x1));ymax=max(imag(x1)) + dx=abs(xmax-xmin)*0.05 + dy=abs(ymax-ymin)*0.05 + if dx<1d-10, dx=0.01,end + if dy<1d-10, dy=0.01,end + legs=[],lstyle=[];lhandle=[] + rect=[xmin-dx;ymin-dy;xmax+dx;ymax+dy]; + f=gcf(); + immediate_drawing= f.immediate_drawing; + f.immediate_drawing = "off"; + a=gca(); + if a.children==[] + a.data_bounds=[rect(1) rect(2);rect(3) rect(4)]; + a.axes_visible="on"; + a.title.text=_("Evans root locus"); + a.x_label.text=_("Real axis"); + a.y_label.text=_("Imaginary axis"); + axes.clip_state = "clipgrf"; + else //enlarge the boundaries + a.data_bounds=[min(a.data_bounds(1,:),[rect(1) rect(2)]); + max(a.data_bounds(2,:),[rect(3) rect(4)])]; + + end + if nroots<>[] then + xpoly(real(nroots),imag(nroots)) + e=gce();e.line_mode="off";e.mark_mode="on"; + e.mark_size_unit="point";e.mark_size=7;e.mark_style=5; + legs=[legs; _("open loop zeroes")] + lhandle=[lhandle; e]; + end + if racines<>[] then + xpoly(real(racines(:,1)),imag(racines(:,1))) + e=gce();e.line_mode="off";e.mark_mode="on"; + e.mark_size_unit="point";e.mark_size=7;e.mark_style=2; + legs=[legs;_("open loop poles")] + lhandle=[lhandle; e]; + end + dx=max(abs(xmax-xmin),abs(ymax-ymin)); + //plot the zeros locations + + + //computes and draw the asymptotic lines + m=degree(n);q=md-m + if q>0 then + la=0:q-1; + so=(sum(racines(:,1))-sum(nroots))/q + i1=real(so);i2=imag(so); + if prod(size(la))<>1 then + ang1=%pi/q*(ones(la)+2*la) + x1=dx*cos(ang1),y1=dx*sin(ang1) + else + x1=0,y1=0, + end + if md==2, + if coeff(d,md)<0 then + x1=0*ones(2),y1=0*ones(2) + end, + end; + if max(k)>0 then + xpoly(i1,i2); + e=gce(); + legs=[legs;_("asymptotic directions")] + lhandle=[lhandle; e]; + + a.clip_state = "clipgrf"; + for i=1:q,xsegs([i1,x1(i)+i1],[i2,y1(i)+i2]),end, + // a.clip_state = "off"; + end + end; + + [n1,n2]=size(racines); + + // assign the colors for each root locus + cmap=f.color_map;cols=1:size(cmap,1); + if a.background==-2 then + cols(and(cmap==1,2))=[]; //remove white + elseif a.background==-1 then + cols(and(cmap==0,2))=[]; //remove black + else + cols(a.background)=[]; + end + cols=cols(modulo(0:n1-1,size(cols,"*"))+1); + + //draw the root locus + xpolys(real(racines)',imag(racines)',cols) + //set info for datatips + E=gce(); + + for k=1:size(E.children,"*") + E.children(k).display_function = "formatEvansTip"; + E.children(k).display_function_data = kk; + end + c=captions(lhandle,legs($:-1:1),"in_upper_right") + c.background=a.background; + + f.immediate_drawing = immediate_drawing; + + if fin=="nptmax" then + warning(msprintf(gettext("%s: Curve truncated to the first %d discretization points.\n"),"evans",nptmax)) + end +endfunction + +function str=formatEvansTip(curve) + //this function is called by the datatip mechanism to format the tip + //string for the evans root loci curves + ud = curve.parent.display_function_data; + pt = curve.data(1:2); + [d,ptp,i,c]=orthProj(curve.parent.data, pt); + K=ud(i)+(ud(i+1)-ud(i))*c; + str=msprintf("r: %.4g %+.4g i\nK: %.4g", pt,K); +endfunction diff --git a/modules/cacsd/macros/findABCD.bin b/modules/cacsd/macros/findABCD.bin Binary files differnew file mode 100755 index 000000000..ca488afff --- /dev/null +++ b/modules/cacsd/macros/findABCD.bin diff --git a/modules/cacsd/macros/findABCD.sci b/modules/cacsd/macros/findABCD.sci new file mode 100755 index 000000000..b57e74f11 --- /dev/null +++ b/modules/cacsd/macros/findABCD.sci @@ -0,0 +1,115 @@ +function [sys,K,Q,Ry,S,rcnd]=findABCD(s,n,l,R,meth,nsmpl,tol,printw) + sys=[];K=[];Q=[];Ry=[];S=[];rcnd=[]; + [nargout,nargin] = argn(0) + //FINDABCD Finds the system matrices and the Kalman gain of a discrete-time + // system, given the system order and the relevant part of the + // R factor of the concatenated block-Hankel matrices, using subspace + // identification techniques (MOESP and/or N4SID). + // + // [SYS,K] = FINDABCD(S,N,L,R,METH,NSMPL,TOL,PRINTW) computes a state- + // space realization SYS = (A,B,C,D) (an ss object), and the Kalman + // predictor gain K (if NSMPL > 0). The model structure is: + // + // x(k+1) = Ax(k) + Bu(k) + Ke(k), k >= 1, + // y(k) = Cx(k) + Du(k) + e(k), + // + // where x(k) and y(k) are vectors of length N and L, respectively. + // + // [SYS,K,Q,Ry,S,RCND] = FINDABCD(S,N,L,R,METH,NSMPL,TOL,PRINTW) also + // returns the state, output, and state-output (cross-)covariance + // matrices Q, Ry, and S (used for computing the Kalman gain), as well as + // the vector RCND of length lr containing the reciprocal condition numbers + // of the matrices involved in rank decisions, least squares or Riccati + // equation solutions, where + // lr = 4, if Kalman gain matrix K is not required, and + // lr = 12, if Kalman gain matrix K is required. + // + // S is the number of block rows in the block-Hankel matrices. + // + // METH is an option for the method to use: + // METH = 1 : MOESP method with past inputs and outputs; + // = 2 : N4SID method; + // = 3 : combined method: A and C via MOESP, B and D via N4SID. + // Default: METH = 3. + // Matrix R, computed by FINDR, should be determined with suitable arguments + // METH and JOBD. METH = 1 and JOBD = 1 must be used in findR, for METH = 1 + // in FINDABCD; METH = 1 must be used in FINDR, for METH = 3 in FINDABCD. + // + // NSMPL is the total number of samples used for calculating the covariance + // matrices and the Kalman predictor gain. This parameter is not needed if + // the covariance matrices and/or the Kalman predictor gain matrix are not + // desired. If NSMPL = 0, then K, Q, Ry, and S are not computed. + // Default: NSMPL = 0. + // + // TOL is the tolerance used for estimating the rank of matrices. + // If TOL > 0, then the given value of TOL is used as a lower bound + // for the reciprocal condition number. + // Default: prod(size(matrix))*epsilon_machine where epsilon_machine + // is the relative machine precision. + // + // PRINTW is a select for printing the warning messages. + // PRINTW = 1: print warning messages; + // = 0: do not print warning messages. + // Default: PRINTW = 0. + // + // The number of output arguments may vary, but should correspond to the + // input arguments, e.g., + // SYS = FINDABCD(S,N,L,R,METH) or + // [SYS,RCND] = FINDABCD(S,N,L,R,METH) just return SYS, or SYS and RCND. + // + // See also FINDAC, FINDBD, FINDBDK, FINDR, ORDER, SIDENT + // + + // V. Sima 18-01-2000. + // + // Revisions: + // + + nin = nargin; + nout = nargout; + // + if nin<8 then + printw = 0; + end + if nin<7 then tol = 0;end + if tol==[] then tol = 0;end + + if nin<6 then nsmpl = 0;end + if nsmpl==[] then nsmpl = 0;end + + if nin<5 then meth = 3;end + if meth==[] then meth = 3;end + + if nin<4 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"findABCD",4,8)); + end + // + // Compute all system matrices. + job = 1; + if nout==1 then + [A,C,B,D] = sident(meth,job,s,n,l,R,tol,nsmpl,[],[],printw); + elseif nout>=2 then + if nsmpl==0 then + // Here K means rcnd. + [A,C,B,D,K] = sident(meth,job,s,n,l,R,tol,nsmpl,[],[],printw); + elseif nout==2 then + [A,C,B,D,K] = sident(meth,job,s,n,l,R,tol,nsmpl,[],[],printw); + elseif nout==3 then + [A,C,B,D,K,Q] = sident(meth,job,s,n,l,R,tol,nsmpl,[],[],printw); + elseif nout==4 then + [A,C,B,D,K,Q,Ry] = sident(meth,job,s,n,l,R,tol,nsmpl,[],[],printw); + elseif nout==5 then + [A,C,B,D,K,Q,Ry,S] = sident(meth,job,s,n,l,R,tol,nsmpl,[],[],printw); + elseif nout==6 then + [A,C,B,D,K,Q,Ry,S,rcnd] = sident(meth,job,s,n,l,R,tol,nsmpl,[],[],printw); + else + error(msprintf(gettext("%s: Wrong number of output arguments: %d to %d expected.\n"),"findABCD",1,6)); + end + else + error(msprintf(gettext("%s: Wrong number of output arguments: %d to %d expected.\n"),"findABCD",1,6)); + end + // + sys = syslin(1,A,B,C,D); + // + // end findABCD +endfunction diff --git a/modules/cacsd/macros/findAC.bin b/modules/cacsd/macros/findAC.bin Binary files differnew file mode 100755 index 000000000..489e77c23 --- /dev/null +++ b/modules/cacsd/macros/findAC.bin diff --git a/modules/cacsd/macros/findAC.sci b/modules/cacsd/macros/findAC.sci new file mode 100755 index 000000000..bdda5148b --- /dev/null +++ b/modules/cacsd/macros/findAC.sci @@ -0,0 +1,77 @@ +function [A,C,rcnd]=findAC(s,n,l,R,meth,tol,printw) + A=[];C=[];rcnd=[]; + [nargout,nargin] = argn(0) + //FINDAC Finds the system matrices A and C of a discrete-time system, given the + // system order and the relevant part of the R factor of the concatenated + // block-Hankel matrices, using subspace identification techniques (MOESP + // or N4SID). + // + // [A,C] = FINDAC(S,N,L,R,METH,TOL,PRINTW) computes the system matrices + // A and C. The model structure is: + // + // x(k+1) = Ax(k) + Bu(k) + Ke(k), k >= 1, + // y(k) = Cx(k) + Du(k) + e(k), + // + // where x(k) and y(k) are vectors of length N and L, respectively. + // + // [A,C,RCND] = FINDAC(S,N,L,R,METH,TOL,PRINTW) also returns the vector + // RCND of length 4 containing the condition numbers of the matrices + // involved in rank decisions. + // + // S is the number of block rows in the block-Hankel matrices. + // + // METH is an option for the method to use: + // METH = 1 : MOESP method with past inputs and outputs; + // = 2 : N4SID method. + // Default: METH = 1. + // Matrix R, computed by FINDR, should be determined with suitable arguments + // METH and JOBD. + // + // TOL is the tolerance used for estimating the rank of matrices. + // If TOL > 0, then the given value of TOL is used as a lower bound + // for the reciprocal condition number. + // Default: prod(size(matrix))*epsilon_machine where epsilon_machine + // is the relative machine precision. + // + // PRINTW is a select for printing the warning messages. + // PRINTW = 1: print warning messages; + // = 0: do not print warning messages. + // Default: PRINTW = 0. + // + // See also FINDABCD, FINDBD, FINDBDK, FINDR, ORDER, SIDENT + // + + // V. Sima 18-01-2000. + // + // Revisions: + // + + nin = nargin; + nout = nargout; + // + if nin<7 then + printw = 0; + end + if nin<6 then tol = 0;end + if tol==[] then tol = 0;end + if nin<5 then meth = 1;end + if meth==[] then meth = 1;end + if nin<4 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"findAC",4,7)); + end + // + // Compute system matrices A and C. + job = 2; + nsmpl = 0; + if nout==1 then + A = sident(meth,job,s,n,l,R,tol,nsmpl,[],[],printw); + elseif nout==2 then + [A,C] = sident(meth,job,s,n,l,R,tol,nsmpl,[],[],printw); + elseif nout==3 then + [A,C,rcnd] = sident(meth,job,s,n,l,R,tol,nsmpl,[],[],printw); + else + error(msprintf(gettext("%s: Wrong number of output arguments: %d to %d expected.\n"),"findAC",1,3)); + end + // + // end findAC +endfunction diff --git a/modules/cacsd/macros/findBDK.bin b/modules/cacsd/macros/findBDK.bin Binary files differnew file mode 100755 index 000000000..07c8fca3d --- /dev/null +++ b/modules/cacsd/macros/findBDK.bin diff --git a/modules/cacsd/macros/findBDK.sci b/modules/cacsd/macros/findBDK.sci new file mode 100755 index 000000000..85730d0a3 --- /dev/null +++ b/modules/cacsd/macros/findBDK.sci @@ -0,0 +1,123 @@ +function [B,D,K,Q,Ry,S,rcnd]=findBDK(s,n,l,R,A,C,meth,job,nsmpl,tol,printw) + B=[];D=[];K=[];Q=[];Ry=[];S=[];rcnd=[]; + [nargout,nargin] = argn(0) + //FINDBDK Finds the system matrices B and D and the Kalman gain of a discrete-time + // system, given the system order, the matrices A and C, and the relevant + // part of the R factor of the concatenated block-Hankel matrices, using + // subspace identification techniques (MOESP or N4SID). + // + // [B,D,K] = FINDBDK(S,N,L,R,A,C,METH,JOB,NSMPL,TOL,PRINTW) computes the + // system matrices B (if JOB = 1), B and D (if JOB = 2), and the Kalman + // predictor gain K (if NSMPL > 0). The model structure is: + // + // x(k+1) = Ax(k) + Bu(k) + Ke(k), k >= 1, + // y(k) = Cx(k) + Du(k) + e(k), + // + // where x(k) and y(k) are vectors of length N and L, respectively. + // + // [B,D,RCND] = FINDBDK(S,N,L,R,A,C,METH,JOB) also returns the vector + // RCND of length 4 containing the reciprocal condition numbers of the + // matrices involved in rank decisions. + // + // [B,D,K,Q,Ry,S,RCND] = FINDBDK(S,N,L,R,A,C,METH,JOB,NSMPL,TOL,PRINTW) also + // returns the state, output, and state-output (cross-)covariance + // matrices Q, Ry, and S (used for computing the Kalman gain), as well as + // the vector RCND of length 12 containing the reciprocal condition numbers + // of the matrices involved in rank decisions, least squares or Riccati + // equation solutions. + // + // S is the number of block rows in the block-Hankel matrices. + // + // METH is an option for the method to use: + // METH = 1 : MOESP method with past inputs and outputs; + // = 2 : N4SID method. + // Default: METH = 2. + // Matrix R, computed by FINDR, should be determined with suitable arguments + // METH and JOBD. METH = 1 and JOBD = 1 must be used in FINDR, for METH = 1 + // in FINDBDK. Using METH = 1 in FINDR and METH = 2 in FINDBDK is allowed. + // + // JOB is an option specifying which system matrices should be computed: + // JOB = 1 : compute the matrix B; + // = 2 : compute the matrices B and D. + // Default: JOB = 2. + // + // NSMPL is the total number of samples used for calculating the covariance + // matrices and the Kalman predictor gain. This parameter is not needed if + // the covariance matrices and/or the Kalman predictor gain matrix are not + // desired. If NSMPL = 0, then K, Q, Ry, and S are not computed. + // Default: NSMPL = 0. + // + // TOL is the tolerance used for estimating the rank of matrices. + // If TOL > 0, then the given value of TOL is used as a lower bound + // for the reciprocal condition number. + // Default: prod(size(matrix))*epsilon_machine where epsilon_machine + // is the relative machine precision. + // + // PRINTW is a select for printing the warning messages. + // PRINTW = 1: print warning messages; + // = 0: do not print warning messages. + // Default: PRINTW = 0. + // + // The number of output arguments may vary, but should correspond to the + // input arguments, e.g., + // B = FINDBDK(S,N,L,R,A,C,METH,1) or + // [B,D] = FINDBDK(S,N,L,R,A,C,METH,2) or + // [B,D,RCND] = FINDBDK(S,N,L,R,A,C,METH,2) + // return B, or B and D, or B, D, and RCND, respectively. + // + // See also FINDABCD, FINDAC, FINDBD, FINDR, ORDER, SIDENT + // + + // V. Sima 18-01-2000. + // + // Revisions: + // V. Sima, July 2000. + // + + nin = nargin; + nout = nargout; + // + if nin<11 then printw = 0;end + if nin<10 then tol = 0;end + if tol==[] then tol = 0,end + if nin<9 then nsmpl = 0;end + if nsmpl==[] then nsmpl = 0;end + if nin<8 then job = 2;end + if job==[] then job = 2;end + if nin<7 then meth = 2;end + if meth == [] then meth = 2;end + if nin<6 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"findBDK",6,11)); + end + // + jobl = job+2; + // + // Compute system matrices B and D. + if nout==1 then + B = sident(meth,jobl,s,n,l,R,tol,nsmpl,A,C,printw); + elseif nout==2 then + // If job = 1 and nsmpl > 0, D means K. + // If job = 1 and nsmpl = 0, D means rcnd. + [B,D] = sident(meth,jobl,s,n,l,R,tol,nsmpl,A,C,printw); + elseif nout==3 then + // If below, job = 1 and nsmpl = 0, D means rcnd, K is not assigned. + // If job = 1 and nsmpl > 0, D means K, K means Q. + [B,D,K] = sident(meth,jobl,s,n,l,R,tol,nsmpl,A,C,printw); + elseif nout==4 then + // If job = 1 and nsmpl > 0, D means K, K means Q, Q means Ry. + [B,D,K,Q] = sident(meth,jobl,s,n,l,R,tol,nsmpl,A,C,printw); + elseif nout==5 then + // If job = 1 and nsmpl > 0, D means K, K means Q, Q means Ry, Ry means S. + [B,D,K,Q,Ry] = sident(meth,jobl,s,n,l,R,tol,nsmpl,A,C,printw); + elseif nout==6 then + // If job = 1 and nsmpl > 0, D means K, K means Q, Q means Ry, + // Ry means S, S means rcnd. + [B,D,K,Q,Ry,S] = sident(meth,jobl,s,n,l,R,tol,nsmpl,A,C,printw); + elseif nout==7 then + [B,D,K,Q,Ry,S,rcnd] = sident(meth,jobl,s,n,l,R,tol,nsmpl,A,C,printw); + else + error(msprintf(gettext("%s: Wrong number of output arguments: %d to %d expected.\n"),"findBDK",1,7)); + end + // + // end findBDK +endfunction diff --git a/modules/cacsd/macros/findR.bin b/modules/cacsd/macros/findR.bin Binary files differnew file mode 100755 index 000000000..ebfd49925 --- /dev/null +++ b/modules/cacsd/macros/findR.bin diff --git a/modules/cacsd/macros/findR.sci b/modules/cacsd/macros/findR.sci new file mode 100755 index 000000000..f9ae1c16e --- /dev/null +++ b/modules/cacsd/macros/findR.sci @@ -0,0 +1,113 @@ +function [R,n,sval,rcnd]=findR(s,y,u,meth,alg,jobd,tol,printw) + R=[];n=[];sval=[];rcnd=[]; + [nargout,nargin] = argn(0) + //FINDR Preprocesses the input-output data for estimating the matrices + //of a linear time-invariant dynamical system, using Cholesky or + //(fast) QR factorization and subspace identification techniques + //(MOESP or N4SID), and estimates the system order. + // + //[R,N] = FINDR(S,Y,U,METH,ALG,JOBD,TOL,PRINTW) returns the processed + //upper triangular factor R of the concatenated block-Hankel matrices + //built from the input-output data, and the order N of a discrete-time + //realization. The model structure is: + // + // x(k+1) = Ax(k) + Bu(k) + w(k), k >= 1, + // y(k) = Cx(k) + Du(k) + e(k). + // + //The vectors y(k) and u(k) are transposes of the k-th rows of Y and U, + //respectively. + // + //S is the number of block rows in the block-Hankel matrices. + // + //METH is an option for the method to use: + //METH = 1 : MOESP method with past inputs and outputs; + // = 2 : N4SID method. + //Default: METH = 1. + // + //ALG is an option for the algorithm to compute the triangular factor of + //the concatenated block-Hankel matrices built from the input-output data: + //ALG = 1 : Cholesky algorithm on the correlation matrix; + // = 2 : fast QR algorithm; + // = 3 : standard QR algorithm. + //Default: ALG = 1. + // + //JOBD is an option to specify if the matrices B and D should later + //be computed using the MOESP approach: + //JOBD = 1 : the matrices B and D should later be computed using + // the MOESP approach; + // = 2 : the matrices B and D should not be computed using + // the MOESP approach. + //Default: JOBD = 2. + //This parameter is not relevant for METH = 2. + // + //TOL is a vector of length 2 containing tolerances: + //TOL(1) is the tolerance for estimating the rank of matrices. + //If TOL(1) > 0, the given value of TOL(1) is used as a + //lower bound for the reciprocal condition number. + //Default: TOL(1) = prod(size(matrix))*epsilon_machine where + // epsilon_machine is the relative machine precision. + //TOL(2) is the tolerance for estimating the system order. + //If TOL(2) >= 0, the estimate is indicated by the index of + //the last singular value greater than or equal to TOL(2). + //(Singular values less than TOL(2) are considered as zero.) + //When TOL(2) = 0, then S*epsilon_machine*sval(1) is used instead + //TOL(2), where sval(1) is the maximal singular value. + //When TOL(2) < 0, the estimate is indicated by the index of the + //singular value that has the largest logarithmic gap to its successor. + //Default: TOL(2) = -1. + // + //PRINTW is a select for printing the warning messages. + //PRINTW = 1: print warning messages; + // = 0: do not print warning messages. + //Default: PRINTW = 0. + // + //[R,N,SVAL,RCND] = FINDR(S,Y,U,METH,ALG,JOBD,TOL,PRINTW) also returns + //the singular values SVAL, used for estimating the order, as well as, + //if meth = 2, the vector RCND of length 2 containing the reciprocal + //condition numbers of the matrices involved in rank decisions or least + //squares solutions. + // + //[R,N] = FINDR(S,Y) assumes U = [] and default values for the + //remaining input arguments. + // + //See also FINDABCD, FINDAC, FINDBD, FINDBDK, ORDER, SIDENT + // + + // V. Sima 18-01-2000. + // + // Revisions: + // V. Sima, July 2000. + // + + nin = nargin; + // + // Assumes one batch only. + batch = 4; + conct = 2; + // + if nin<8 then + printw = 0; + end + if nin<7 then + tol(1:2) = [0,-1] + end + if nin<6 then jobd = 2; end + if jobd==[] then jobd = 2,end + + if nin<5 then alg = 1;end + if alg==[] then alg = 1;end + + if nin<4 then meth = 1;end + if meth==[] then meth = 1;end + if nin<3 then + u = []; + end + // + if meth==1 then + [R,n,sval] = sorder(meth,alg,jobd,batch,conct,s,y,u,tol,printw); + else + [R,n,sval,rcnd] = sorder(meth,alg,jobd,batch,conct,s,y,u,tol,printw); + end + // + // end findR +endfunction diff --git a/modules/cacsd/macros/findx0BD.bin b/modules/cacsd/macros/findx0BD.bin Binary files differnew file mode 100755 index 000000000..a8a88f15f --- /dev/null +++ b/modules/cacsd/macros/findx0BD.bin diff --git a/modules/cacsd/macros/findx0BD.sci b/modules/cacsd/macros/findx0BD.sci new file mode 100755 index 000000000..2554038f2 --- /dev/null +++ b/modules/cacsd/macros/findx0BD.sci @@ -0,0 +1,120 @@ +function [x0,B,D,V,rcnd]=findx0BD(A,C,y,u,withx0,withd,tol,printw) + x0=[];B=[];D=[];V=[];rcnd=[]; + [nargout,nargin] = argn(0) + //FINDX0BD Estimates the initial state and/or the matrices B and D of a + // discrete-time linear system, given the (estimated) system + // matrices A, C, and a set of input/output data. + // + // [X0,B,D] = FINDX0BD(A,C,Y,U,WITHX0,WITHD,TOL,PRINTW) estimates the + // initial state X0 and the matrices B and D of a discrete-time + // system using the system matrices A, C, output data Y and the input + // data U. The model structure is : + // + // x(k+1) = Ax(k) + Bu(k), k >= 1, + // y(k) = Cx(k) + Du(k), + // + // The vectors y(k) and u(k) are transposes of the k-th rows of Y and U, + // respectively. + // + // WITHX0 is a select for estimating the initial state x0. + // WITHX0 = 1: estimate x0; + // = 0: do not estimate x0. + // Default: WITHX0 = 1. + // + // WITHD is a select for estimating the matrix D. + // WITHD = 1: estimate the matrix D; + // = 0: do not estimate the matrix D. + // Default: WITHD = 1. + // + // TOL is the tolerance used for estimating the rank of matrices. + // If TOL > 0, then the given value of TOL is used as a lower bound + // for the reciprocal condition number. + // Default: prod(size(matrix))*epsilon_machine where epsilon_machine + // is the relative machine precision. + // + // PRINTW is a select for printing the warning messages. + // PRINTW = 1: print warning messages; + // = 0: do not print warning messages. + // Default: PRINTW = 0. + // + // [x0,B,D,V,rcnd] = FINDX0BD(A,C,Y,U) also returns the orthogonal + // matrix V which reduces the system state matrix A to a real Schur + // form, as well as some estimates of the reciprocal condition numbers + // of the matrices involved in rank decisions. + // + // B = FINDX0BD(A,C,Y,U,0,0) returns B only, and + // [B,D] = FINDX0BD(A,C,Y,U,0) returns B and D only. + // + // See also FINDBD, INISTATE + // + + // V. Sima 13-05-2000. + // + // For efficiency, most errors are checked in the mexfile findBD. + // + // Revisions: + // V. Sima, July 2000. + // + ni = nargin; + nout = nargout; + if ni<4 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"findx0BD",4,8)); + end + if nout<1 then + error(msprintf(gettext("%s: Wrong number of output arguments: At least %d expected.\n"),"findx0BD",1)); + end + // + if ni<8 then + printw = 0; + end + if ni<7 then tol = 0;end + if tol==[] then tol = 0;end + if ni<6 then + withd = 1; + elseif withd ==[] then + withd = 1; + elseif (withd~=0)&(withd~=1) then + warning(msprintf(gettext("%s: Wrong value for input argument #%d: %d or %d expected.\n"),"findx0BD",6,0,1)) + end + if ni<5 then withx0 = 1;end + if withx0 ==[] then withx0 = 1;end + job = withd+1; + // + if withx0==1 then + if withd==1 then + [x0,B,D,Vl,rcndl] = findBD(withx0,1,job,A,C,y,u,tol,printw); + if nout>3 then + V = Vl; + end + if nout>4 then + rcnd = rcndl; + end + else + [x0,B,Vl,rcndl] = findBD(withx0,1,job,A,C,y,u,tol,printw); + if nout>2 then + D = Vl; + end + if nout>3 then + V = rcndl; + end + end + else + // Below, x0 means B, and B means D or V ! + if withd==1 then + [x0,B,Vl,rcndl] = findBD(withx0,1,job,A,C,y,u,tol,printw); + if nout>2 then + D = Vl; + end + if nout>3 then + V = rcndl; + end + else + [x0,B,Vl] = findBD(withx0,1,job,A,C,y,u,tol,printw); + if nout>2 then + D = Vl; + end + end + end + // + // end findx0BD +endfunction diff --git a/modules/cacsd/macros/flts.bin b/modules/cacsd/macros/flts.bin Binary files differnew file mode 100755 index 000000000..dd09083e7 --- /dev/null +++ b/modules/cacsd/macros/flts.bin diff --git a/modules/cacsd/macros/flts.sci b/modules/cacsd/macros/flts.sci new file mode 100755 index 000000000..a76b17d12 --- /dev/null +++ b/modules/cacsd/macros/flts.sci @@ -0,0 +1,75 @@ + +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - Serge Steer +// +// 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 [y,xf]=flts(u,sl,x0) + + [lhs,rhs]=argn(0) + if type(u)<>1 then error(53,1),end + if rhs<=1 then error(39),end + [nu,mu]=size(u) + + select typeof(sl) + case "state-space" then + if rhs==2 then x0=sl.X0,end + [nb,mb]=size(sl.B) + if mb<>nu then error(60),end; + if sl.dt=="c" then error(94,2),end; + np=max(degree(sl.D)) + [xf,x]=ltitr(sl.A,sl.B,u(:,1:(mu-np)),x0) + D=sl.D + if type(D)==1 then + y=sl.C*x+D*u + else + y=sl.C*x+rtitr(D,eye(D),u) + end + case "rational" then + if lhs>1 then + error(msprintf(gettext("%s: Wrong number of output argument: %d expected.\n"),"flts",1)), + end + [num,den]=sl(["num","den"]);[ns,ne]=size(num) + if sl.dt=="c" then error(94,2),end; + if ne<>nu then error(60), end; + for l=1:1:ns, + pp=den(l,1); + for k=2:ne,[pg,uu]=bezout(pp,den(l,k)),pp=pp*uu(1,2),end + nden(l)=pp + for k=1:ne,nnum(l,k)=num(l,k)*pdiv(pp,den(l,k)),end, + end; + for l=1:ns, nm(l)=degree(nden(l))-max(degree(nnum(l,:))),end + ly=mu+min(nm) + if rhs==3 then + [mx,nx]=size(x0);maxdgd=max(degree(nden)) + if nx<maxdgd then + error(msprintf(gettext("%s: At least %s past values needed.\n"),"flts",string(maxdgd))) + end; + if mx<>ns+ne then error(60),end + end; + y=0*ones(ns,ly); + for l=1:ns + ddl=degree(nden(l)) + dnl=max(degree(nnum(l,:))) + lent=ly-ddl+dnl + select rhs + case 2 then yl=rtitr(nnum(l,:),nden(l),u(:,1:lent)); + [nn,mm]=size(yl); + y(l,1:mm)=yl; + // y=y(:,1:lent); + case 3 then + up=x0(1:ne,maxdgd-ddl+1:maxdgd); + yp=x0(ne+l,maxdgd-ddl+1:maxdgd); + y(l,:)=rtitr(nnum(l,:),nden(l),u(:,1:lent),up,yp); + end; + end, + l=size(y,2); + y=y(:,1:min(mu,l)); + else + error(97,2) + end; +endfunction diff --git a/modules/cacsd/macros/formatBlackTip.bin b/modules/cacsd/macros/formatBlackTip.bin Binary files differnew file mode 100755 index 000000000..1eacb291c --- /dev/null +++ b/modules/cacsd/macros/formatBlackTip.bin diff --git a/modules/cacsd/macros/formatBlackTip.sci b/modules/cacsd/macros/formatBlackTip.sci new file mode 100755 index 000000000..8676c09e9 --- /dev/null +++ b/modules/cacsd/macros/formatBlackTip.sci @@ -0,0 +1,20 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 1998-2010 - INRIA - Serge Steer +// Copyright (C) 2010 - DIGITEO - Yann COLLETTE +// 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 str=formatBlackTip(datatipHandle) + //This function is called by the datatip mechanism to format the tip + //string for black curves. + ud = datatipHandle.parent.display_function_data; + pt = datatipHandle.data(1:2); + [d,ptp,i,c]=orthProj(datatipHandle.parent.data, pt); + disp(c) + f=ud(i)+(ud(i+1)-ud(i))*c; + str=msprintf("%.4g°\n%.4g"+_("dB")+"\n%.4g"+_("Hz"), pt,f); + +endfunction diff --git a/modules/cacsd/macros/formatBodeMagTip.bin b/modules/cacsd/macros/formatBodeMagTip.bin Binary files differnew file mode 100755 index 000000000..365943c24 --- /dev/null +++ b/modules/cacsd/macros/formatBodeMagTip.bin diff --git a/modules/cacsd/macros/formatBodeMagTip.sci b/modules/cacsd/macros/formatBodeMagTip.sci new file mode 100755 index 000000000..42c389001 --- /dev/null +++ b/modules/cacsd/macros/formatBodeMagTip.sci @@ -0,0 +1,14 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 1985-2010 - INRIA - Serge Steer +// 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 str = formatBodeMagTip(datatipHandle) + // This function is called by the datatips mechanism to format the tip + // string for the magnitude bode curves + pt = datatipHandle.data(1:2); + str = msprintf("%.4g"+_("Hz")+"\n%.4g"+_("dB"), pt(1), pt(2)); +endfunction diff --git a/modules/cacsd/macros/formatBodePhaseTip.bin b/modules/cacsd/macros/formatBodePhaseTip.bin Binary files differnew file mode 100755 index 000000000..125da2f23 --- /dev/null +++ b/modules/cacsd/macros/formatBodePhaseTip.bin diff --git a/modules/cacsd/macros/formatBodePhaseTip.sci b/modules/cacsd/macros/formatBodePhaseTip.sci new file mode 100755 index 000000000..b7978c395 --- /dev/null +++ b/modules/cacsd/macros/formatBodePhaseTip.sci @@ -0,0 +1,14 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 1985-2010 - INRIA - Serge Steer +// 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 str = formatBodePhaseTip(datatipHandle) + // This function is called by the datatip mechanism to format the tip + // string for the bode phase curves + pt = datatipHandle.data(1:2) + str = msprintf("%.4g"+_("Hz")+"\n %.4g"+"°", pt(1), pt(2)); +endfunction diff --git a/modules/cacsd/macros/formatGainplotTip.bin b/modules/cacsd/macros/formatGainplotTip.bin Binary files differnew file mode 100755 index 000000000..4cd4d1e27 --- /dev/null +++ b/modules/cacsd/macros/formatGainplotTip.bin diff --git a/modules/cacsd/macros/formatGainplotTip.sci b/modules/cacsd/macros/formatGainplotTip.sci new file mode 100755 index 000000000..63b994dd1 --- /dev/null +++ b/modules/cacsd/macros/formatGainplotTip.sci @@ -0,0 +1,14 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge Steer +// 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 str = formatGainplotTip(datatipHandle) + //this function is called by the datatips mechanism to format the tip + //string for the magnitude bode curves + pt = datatipHandle.data(1:2); + str=msprintf("%.4g"+_("Hz")+"\n%.4g"+_("dB"), pt(1),pt(2)) +endfunction diff --git a/modules/cacsd/macros/formatHallModuleTip.bin b/modules/cacsd/macros/formatHallModuleTip.bin Binary files differnew file mode 100755 index 000000000..82f97ba4b --- /dev/null +++ b/modules/cacsd/macros/formatHallModuleTip.bin diff --git a/modules/cacsd/macros/formatHallModuleTip.sci b/modules/cacsd/macros/formatHallModuleTip.sci new file mode 100755 index 000000000..85f1387a1 --- /dev/null +++ b/modules/cacsd/macros/formatHallModuleTip.sci @@ -0,0 +1,13 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 str=formatHallModuleTip(datatipH) + //this function is called by the datatip mechanism to format the tip + //string for the Hall charts iso module curves + str=msprintf("%.2g"+_("dB"), datatipH.parent.display_function_data); +endfunction diff --git a/modules/cacsd/macros/formatHallPhaseTip.bin b/modules/cacsd/macros/formatHallPhaseTip.bin Binary files differnew file mode 100755 index 000000000..4b3411e87 --- /dev/null +++ b/modules/cacsd/macros/formatHallPhaseTip.bin diff --git a/modules/cacsd/macros/formatHallPhaseTip.sci b/modules/cacsd/macros/formatHallPhaseTip.sci new file mode 100755 index 000000000..30f0e5b74 --- /dev/null +++ b/modules/cacsd/macros/formatHallPhaseTip.sci @@ -0,0 +1,14 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 str=formatHallPhaseTip(datatipH) + //This function is called by the datatip mechanism to format the tip + //string for the Hall charts iso phase curves + str=msprintf("%.2g°", datatipH.parent.display_function_data); +endfunction + diff --git a/modules/cacsd/macros/formatNicholsGainTip.bin b/modules/cacsd/macros/formatNicholsGainTip.bin Binary files differnew file mode 100755 index 000000000..78dfa0d6c --- /dev/null +++ b/modules/cacsd/macros/formatNicholsGainTip.bin diff --git a/modules/cacsd/macros/formatNicholsGainTip.sci b/modules/cacsd/macros/formatNicholsGainTip.sci new file mode 100755 index 000000000..36f64d6e2 --- /dev/null +++ b/modules/cacsd/macros/formatNicholsGainTip.sci @@ -0,0 +1,13 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 str=formatNicholsGainTip(datatipHandle) + //This function is called by the datatip mechanism to format the tip + //string for the Nichols chart iso gain curves. + str=msprintf("%.2g"+_("dB"),datatipHandle.parent.display_function_data); +endfunction diff --git a/modules/cacsd/macros/formatNicholsPhaseTip.bin b/modules/cacsd/macros/formatNicholsPhaseTip.bin Binary files differnew file mode 100755 index 000000000..077c74a39 --- /dev/null +++ b/modules/cacsd/macros/formatNicholsPhaseTip.bin diff --git a/modules/cacsd/macros/formatNicholsPhaseTip.sci b/modules/cacsd/macros/formatNicholsPhaseTip.sci new file mode 100755 index 000000000..1ea9efa64 --- /dev/null +++ b/modules/cacsd/macros/formatNicholsPhaseTip.sci @@ -0,0 +1,13 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 str=formatNicholsPhaseTip(datatipHandle) + //This function is called by the datatip mechanism to format the tip + //string for the Nichols chart iso phase curves. + str=msprintf("%.2g°",datatipHandle.parent.display_function_data) +endfunction diff --git a/modules/cacsd/macros/formatNyquistTip.bin b/modules/cacsd/macros/formatNyquistTip.bin Binary files differnew file mode 100755 index 000000000..aafc23c19 --- /dev/null +++ b/modules/cacsd/macros/formatNyquistTip.bin diff --git a/modules/cacsd/macros/formatNyquistTip.sci b/modules/cacsd/macros/formatNyquistTip.sci new file mode 100755 index 000000000..28313ebf3 --- /dev/null +++ b/modules/cacsd/macros/formatNyquistTip.sci @@ -0,0 +1,17 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 1984-2011 - INRIA - Serge STEER +// 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 str=formatNyquistTip(datatipHandle) + //This function is called by the datatip mechanism to format the tip + //string for the nyquist curves. + ud = datatipHandle.parent.display_function_data; + pt = datatipHandle.data(1:2); + [d,ptp,i,c]=orthProj(datatipHandle.parent.data, pt); + f=ud(i)+(ud(i+1)-ud(i))*c; + str=msprintf("%.4g%+.4gi\n%.4g"+_("Hz"), pt,f); +endfunction diff --git a/modules/cacsd/macros/formatPhaseplotTip.bin b/modules/cacsd/macros/formatPhaseplotTip.bin Binary files differnew file mode 100755 index 000000000..d6b561036 --- /dev/null +++ b/modules/cacsd/macros/formatPhaseplotTip.bin diff --git a/modules/cacsd/macros/formatPhaseplotTip.sci b/modules/cacsd/macros/formatPhaseplotTip.sci new file mode 100755 index 000000000..01572d6c5 --- /dev/null +++ b/modules/cacsd/macros/formatPhaseplotTip.sci @@ -0,0 +1,14 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 1985-2010 - INRIA - Serge Steer +// 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 str = formatPhaseplotTip(datatipHandle) + //this function is called by the datatips mechanism to format the tip + //string for the magnitude bode curves + pt = datatipHandle.data(1:2) + str = msprintf("%.4g"+_("Hz")+"\n %.4g"+"°", pt(1), pt(2)); +endfunction diff --git a/modules/cacsd/macros/formatSgridDampingTip.bin b/modules/cacsd/macros/formatSgridDampingTip.bin Binary files differnew file mode 100755 index 000000000..9827e96e3 --- /dev/null +++ b/modules/cacsd/macros/formatSgridDampingTip.bin diff --git a/modules/cacsd/macros/formatSgridDampingTip.sci b/modules/cacsd/macros/formatSgridDampingTip.sci new file mode 100755 index 000000000..33321a71b --- /dev/null +++ b/modules/cacsd/macros/formatSgridDampingTip.sci @@ -0,0 +1,13 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 str = formatSgridDampingTip(datatipHandle) + //This function is called by the datatip mechanism to format the tip + //string for the sgrid chart iso damping factor curves. + str = msprintf("%.2g%%", datatipHandle.parent.display_function_data * 100); +endfunction diff --git a/modules/cacsd/macros/formatSgridFreqTip.bin b/modules/cacsd/macros/formatSgridFreqTip.bin Binary files differnew file mode 100755 index 000000000..8e0f10f15 --- /dev/null +++ b/modules/cacsd/macros/formatSgridFreqTip.bin diff --git a/modules/cacsd/macros/formatSgridFreqTip.sci b/modules/cacsd/macros/formatSgridFreqTip.sci new file mode 100755 index 000000000..507fd7335 --- /dev/null +++ b/modules/cacsd/macros/formatSgridFreqTip.sci @@ -0,0 +1,13 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 str = formatSgridFreqTip(datatipHandle) + //This function is called by the datatip mechanism to format the tip + //string for the sgrid chart iso natural frequency curves. + str = msprintf("%.2g"+_("rad/sec"),datatipHandle.parent.display_function_data); +endfunction diff --git a/modules/cacsd/macros/formatZgridDampingTip.bin b/modules/cacsd/macros/formatZgridDampingTip.bin Binary files differnew file mode 100755 index 000000000..1f54f009f --- /dev/null +++ b/modules/cacsd/macros/formatZgridDampingTip.bin diff --git a/modules/cacsd/macros/formatZgridDampingTip.sci b/modules/cacsd/macros/formatZgridDampingTip.sci new file mode 100755 index 000000000..334fa1958 --- /dev/null +++ b/modules/cacsd/macros/formatZgridDampingTip.sci @@ -0,0 +1,14 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2005 - INRIA - Farid Belahcene +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 str = formatZgridDampingTip(datatipHandle) + //This function is called by the datatip mechanism to format the tip + //string for the zgrid chart iso damping factor curves. + str = msprintf("%.2g%%", datatipHandle.parent.display_function_data * 100); +endfunction diff --git a/modules/cacsd/macros/formatZgridFreqTip.bin b/modules/cacsd/macros/formatZgridFreqTip.bin Binary files differnew file mode 100755 index 000000000..7155464a4 --- /dev/null +++ b/modules/cacsd/macros/formatZgridFreqTip.bin diff --git a/modules/cacsd/macros/formatZgridFreqTip.sci b/modules/cacsd/macros/formatZgridFreqTip.sci new file mode 100755 index 000000000..88197f349 --- /dev/null +++ b/modules/cacsd/macros/formatZgridFreqTip.sci @@ -0,0 +1,14 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2005 - INRIA - Farid Belahcene +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 str = formatZgridFreqTip(datatipHandle) + //This function is called by the datatip mechanism to format the tip + //string for the zgrid chart iso natural frequency curves. + str = msprintf("%.2gπ/dt rad/sec",datatipHandle.parent.display_function_data); +endfunction diff --git a/modules/cacsd/macros/fourplan.bin b/modules/cacsd/macros/fourplan.bin Binary files differnew file mode 100755 index 000000000..5ddbd1985 --- /dev/null +++ b/modules/cacsd/macros/fourplan.bin diff --git a/modules/cacsd/macros/fourplan.sci b/modules/cacsd/macros/fourplan.sci new file mode 100755 index 000000000..cd65e5e20 --- /dev/null +++ b/modules/cacsd/macros/fourplan.sci @@ -0,0 +1,21 @@ + +// 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 [P11,P12,P21,P22]=fourplan(P,r) + //returns the four plants associated with the augmented plant P. + // r is the size of P22 and P=[P11,P12;P21,P22]. + + [A,B1,B2,C1,C2,D11,D12,D21,D22]=smga(P,r); + dom=P(7); + P11=syslin(dom,A,B1,C1,D11); + P12=syslin(dom,A,B2,C1,D12); + P21=syslin(dom,A,B1,C2,D21); + P22=syslin(dom,A,B2,C2,D22); +endfunction diff --git a/modules/cacsd/macros/frep2tf.bin b/modules/cacsd/macros/frep2tf.bin Binary files differnew file mode 100755 index 000000000..234f4a8f5 --- /dev/null +++ b/modules/cacsd/macros/frep2tf.bin diff --git a/modules/cacsd/macros/frep2tf.sci b/modules/cacsd/macros/frep2tf.sci new file mode 100755 index 000000000..9108bf599 --- /dev/null +++ b/modules/cacsd/macros/frep2tf.sci @@ -0,0 +1,134 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - Serge Steer +// Copyright (C) ENPC - +// +// 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 [best_h,best_w]=frep2tf(frq,repf,dg,dom,tols,weight) + // iterative use of frep2tf_b jpc fd 1997 + + // Copyright INRIA + [lhs,rhs]=argn(0); + if rhs <= 3 then dom="c" ; end + if rhs <= 4 then + rtol=1.e-2; atol=1.e-4, N=10; + else + rtol=tols(1);atol=tols(2);N=tols(3); + end + if dom==[] then dom="c";end + if dom=="d" then dom=1;end + if rhs <=5 then + [h,err]=frep2tf_b(frq,repf,dg,dom); + best_w = []; + else + [h,err]=frep2tf_b(frq,repf,dg,dom,weight); + best_w = weight; + end + best_h = h ; + for k=1:N + if dom=="c" then + // weight=(1)./abs(freq(h('den'),1,%i*frq*2*%pi)); + weight=(1)./horner(h("den"),%i*frq*2*%pi); + else + weight=(1)./horner(h("den"),exp(dom*%i*frq*2*%pi)); + end + [h,err1]=frep2tf_b(frq,repf,dg,dom,weight); + if ( (abs(err-err1) < rtol *err & err > err1 )| err1 < atol) then break;end; + if err1 < err then best_err = err1 ; best_h = h; end + err=err1; + mprintf(gettext("%s: Iteration %s, error=%s.\n"), "frep2tf", part(string(k+1),1:5), string(err1)); + end +endfunction + +function [h,err]=frep2tf_b(frq,repf,dg,dom,weight) + // steer, jpc, fd 1997 (Nov) + //============================ + [lhs,rhs]=argn(0); + // test the system type 'c' 'd' or dt + if rhs <= 3 then dom="c" ; end + if rhs <= 4 then weight=[];end + if dom==[] then dom="c";end + if dom=="d" then dom=1;end + n=size(frq,"*"); + if dom=="c" then + w=2*%i*%pi*matrix(frq,n,1); + else + w=exp(2*%i*%pi*dom*matrix(frq,n,1)); + end + //initialization + m=2*dg + //We compute the linear system to be solved: + //w(k)=%i* frq(k)*2pi + //for k=1,n sum(a_i*(w(k))^i,i=1,dg) + // -repf(k)*sum(b_i*(w(k))^i,i=1,dg) = 0 + //with sum x_i = 1 + //building Van der monde matrix ( w_i^j ) i=1,n j=0:dg-1 + a1=w.*.[ones(1,dg)]; + //0.^0 is not accepted in Scilab.... + a1=[ones(n,1),a1.^(ones(n,1).*.[1:(dg)])]; + a2=a1; for k=1:n; a2(k,:)= -repf(k)*a2(k,:);end + a=[a1,a2]; + // Computing constraints + // We impose N(i wk) - repfk D(i wk) =0 for k=imax + // as follows: + // N(i wk) = repfk*(1+%i*b) + // D(i wk) = 1+%i*b + // L*[x;b]=[repfk;1] + // Least squ. pb is min norm of [A,0] [x;b] + // under constraint L*[x;b]=[repfk;1] + [rmax,imax]=max(abs(repf)) + L2=a(imax,1:dg+1); + L=[zeros(L2),L2,%i; + L2,zeros(L2),repf(imax)*%i]; + BigL=[real(L);imag(L)] + c=[1;repf(imax)]; + Bigc=[real(c);imag(c)]; + [ww,dim]=rowcomp(BigL); + BigL=ww*BigL;Bigc=ww*Bigc; + BigL=BigL(1:dim,:);Bigc=Bigc(1:dim,:); + + a=[a,zeros(size(a,1),1)]; + // auto renormalization : if weight is not given + if dom == "c" then + if weight==[] then + nn= sqrt(sum(abs(a).^2,"c"))+ones(n,1); + a=a./(nn*ones(1,size(a,2))); + end + end + // user given renormalization + if weight<>[] then + if size(frq,"*")<>size(weight,"*") then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same numbers of elements expected.\n"),"frep2tf",1,5)) + end + w1=weight(:)*ones(1,size(a,2)); + a= w1.*a; + end + BigA=[real(a);imag(a)]; + // Constraints BigL x =Bigc + // + x=LSC(BigA,BigL,Bigc); + x=x(1:$-1); + + h=syslin(dom,poly(x(1:dg+1),"s","c"),poly([x((dg+2):$)],"s","c")) + if lhs==2 then + repf1=repfreq(h,frq); + err = sum(abs(repf1(:)-repf(:)))/n; + end +endfunction + +function [x]=LSC(A,L,c) + // Ax=0 Least sq. + Lx = c + [W,rk]=colcomp(L); + LW=L*W; + Anew=A*W + A1=Anew(:,1:($-rk)) + A2=Anew(:,($-rk+1:$)); + x2=inv(LW(:,$-rk+1:$))*c + b= -A2*x2 + x1=A1\b + x=W*[x1;x2] +endfunction diff --git a/modules/cacsd/macros/freson.bin b/modules/cacsd/macros/freson.bin Binary files differnew file mode 100755 index 000000000..d86c03a54 --- /dev/null +++ b/modules/cacsd/macros/freson.bin diff --git a/modules/cacsd/macros/freson.sci b/modules/cacsd/macros/freson.sci new file mode 100755 index 000000000..a27394a73 --- /dev/null +++ b/modules/cacsd/macros/freson.sci @@ -0,0 +1,42 @@ +// 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 fr=freson(h) + [lhs,rhs]=argn(0); + [n,d]=h(["num","den"]); + if type(n)==1 then + n=poly(n,varn(d),"c"); + end + if coeff(d,0)==0 then + error(msprintf(_("%s: Wrong value for input argument #%d: infinite gain at zero frequency.\n"),"freson",1)) + end + //look for omega such that derivative of magn. is zero + niw=horner(n,%i*poly(0,"w")); + diw=horner(d,%i*poly(0,"w")); + niw=real(niw*conj(niw));diw=real(diw*conj(diw)); + modul_d=derivat(niw/diw);w=roots(modul_d.num); + + // get extreme points + k=find(imag(w)==0&real(w)>=0); + if k==[] then + fr=[]; + g=[]; + return + end + w=gsort(real(w(k)),"g","i"); + + //find maximums + wx=max(w)+0.5; + if horner(modul_d,wx)<0 then + w=w($:-2:1); + else + w=w($-1:-2:1); + end + fr=w/(2*%pi); +endfunction diff --git a/modules/cacsd/macros/fspec.bin b/modules/cacsd/macros/fspec.bin Binary files differnew file mode 100755 index 000000000..bf6ca7dca --- /dev/null +++ b/modules/cacsd/macros/fspec.bin diff --git a/modules/cacsd/macros/fspec.sci b/modules/cacsd/macros/fspec.sci new file mode 100755 index 000000000..f76352bde --- /dev/null +++ b/modules/cacsd/macros/fspec.sci @@ -0,0 +1,41 @@ + +// 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 [gm]=fspec(g) + // computes a spectral factorization: + // g = gtild(gm)*gm + //with stable gm and gm^-1 ( gm^-1 = invsyslin(gm) ). + //-- g: syslin list defining the linear system g + //-- gm: + //Assumptions: + //- g is invertible ( inv(D) exists ), + //- g and g^1 (invsyslin(g)) have no poles on the imaginary axis. + //- gtild(g) = g. + // (poles and zeros of g are symmetric wrt imaginary axis)) + //- g(+oo) = D is positive definite. + //! + + 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"),"fspec",1)) + end + if g.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"fspec",1)) + end + flag=0; + if typeof(g)=="rational" then g=tf2ss(g),flag=1;end + [r1,r,d]=dtsi(g),[a,b,c]=r(2:4), + ari=a-b*inv(d)*c, + rri=b*inv(d)*b',qri=-c'*inv(d)*c, + x=riccati(ari,rri,qri,"c"), + id=sqrtm(d), + gm=syslin("c",a,b,inv(id)*(c+b'*x),id), + gm=minss(gm) + if flag==1 then gm=ss2tf(gm);end; +endfunction diff --git a/modules/cacsd/macros/fspecg.bin b/modules/cacsd/macros/fspecg.bin Binary files differnew file mode 100755 index 000000000..56e0d0dd3 --- /dev/null +++ b/modules/cacsd/macros/fspecg.bin diff --git a/modules/cacsd/macros/fspecg.sci b/modules/cacsd/macros/fspecg.sci new file mode 100755 index 000000000..95f5071d4 --- /dev/null +++ b/modules/cacsd/macros/fspecg.sci @@ -0,0 +1,34 @@ + +// 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 [gm]=fspecg(g) + // gm=fspecg(g) : stable factorization. + // g and gm are continuous-time linear systems in state-space form. + // gtild(g)*g = gtild(gm)*gm + //with gm stable. + // Imaginary-axis poles are forbidden. + // + //! + if typeof(g)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear system expected.\n"),"fspecg",1)) + end + if g.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"fspecg",1)) + end + + [a,b,c,d]=abcd(g), + g=[]; + a=-a; + b=-b; + h=[-a',c'*c; + 0*eye(a),a]; + x=ric_desc(h);h=[] + gm=syslin("c",-a'+c'*c*x,-c',b'-d'*c*x,d')'; +endfunction diff --git a/modules/cacsd/macros/fstabst.bin b/modules/cacsd/macros/fstabst.bin Binary files differnew file mode 100755 index 000000000..d05cc50db --- /dev/null +++ b/modules/cacsd/macros/fstabst.bin diff --git a/modules/cacsd/macros/fstabst.sci b/modules/cacsd/macros/fstabst.sci new file mode 100755 index 000000000..cf66f7221 --- /dev/null +++ b/modules/cacsd/macros/fstabst.sci @@ -0,0 +1,68 @@ + +// 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 [J]=fstabst(Stplant,r) + //[J]=fstabst(Stplant,r) + // Parametrization of all stabilizing feedbacks. + //-- Stplant=[ Stplant11 Stplant12; + // Stplant21 Stplant22] + // (in state-space or transfer form: conversion in state-space is + // done for the computations) + //-- r = size of Stplant22 subsystem (2,2) block of Stplant + // + // j =[ j11 j12; + // j21 j22] + // K is a stablizing controller iff K=LFT(J,r,Q) with Q stable + //! + if and(typeof(Stplant)<>["rational","state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"fstabst",1)) + end + if Stplant.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"fstabst",1)) + end + flag=0; + if typeof(Stplant)=="rational" then Stplant=tf2ss(Stplant),flag=1;end + + + [LHS,RHS]=argn(0); + [a,b1,b2,c1,c2,d11,d12,d21,d22]=smga(Stplant,r), + Rd1=d12'*d12, + R12=sqrtm(Rd1); + Rd2=d21*d21', + R22=sqrtm(Rd2); + p=r(2),r=r(1); + //------------- + [s1,s2,t]=size(Stplant); + [w1,k1]=rowcomp(d12),do1=w1(k1+1:s1-r,:)', + if do1==[] then do1=0,end, + [w2,k2]=rowcomp(d21'),do2=w2(k2+1:s2-p,:), + if do2==[] then do2=0,end, + //gains f and h + //------------- + ar1=a-b2*inv(Rd1)*d12'*c1,br1=b2*inv(Rd1)*b2', + cr1=c1'*do1*do1'*c1, + xc=riccati(ar1,br1,cr1,"cont"), + f=inv(Rd1)*(b2'*xc+d12'*c1), + ar2=(a-b1*d21'*inv(Rd2)*c2)',br2=c2'*inv(Rd2)*c2, + cr2=b1*do2'*do2*b1', + xo=riccati(ar2,br2,cr2,"cont"), + h=(b1*d21'+xo*c2')*inv(Rd2), + // J: + //--- + aj=a-b2*f-h*c2+h*d22*f; + bj=[h ,(b2-h*d22)*inv(R12)], + cj=[-f; + -inv(R22)*(c2-d22*f)], + dj=[0*ones(p,r) eye(p,p)*inv(R12); + inv(R22)*eye(r,r) d22], + //Normalization to get inner and co-inner factors + J=syslin("c",aj,bj,cj,dj), + if flag==1 then J=ss2tf(J);end +endfunction diff --git a/modules/cacsd/macros/g_margin.bin b/modules/cacsd/macros/g_margin.bin Binary files differnew file mode 100755 index 000000000..f6def35b9 --- /dev/null +++ b/modules/cacsd/macros/g_margin.bin diff --git a/modules/cacsd/macros/g_margin.sci b/modules/cacsd/macros/g_margin.sci new file mode 100755 index 000000000..7c33f5b8c --- /dev/null +++ b/modules/cacsd/macros/g_margin.sci @@ -0,0 +1,74 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2013 - Scilab Enterprises - Paul Bignier +// Copyright (C) INRIA - Author: Serge Steer +// +// 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 [gm,fr] = g_margin(h) + // Compute the gain margin of a SISO transfer function + + if argn(2) < 1 then + error(msprintf(_("%s: Wrong number of input argument(s): %d expected.\n"),"g_margin",1)); + end + + select typeof(h) + case "rational" then + case "state-space" then + h=ss2tf(h) + else + error(97,1), + end; + if or(size(h)<>[1 1]) then + error(msprintf(_("%s: Wrong size for input argument #%d: Single input, single output system expected.\n"),"g_margin",1)) + end + // + epsr=1.e-7;//used for testing if complex numbers are real + eps1=1.e-7;//used for testing if complex numbers have a modulus near 1 + epssing=1e-10; //used for testing if arguments are not singular points of h + if h.dt=="c" then //continuous time case + // get s such as h(s)=h(-s) and s=iw + s=%i*poly(0,"w"); + //compute h(s)-h(-s)=num/den + num=imag(horner(h.num,s)*conj(horner(h.den,s))) + den=real(horner(h.den,s)*conj(horner(h.den,s))) + //necessary condition + w=roots(num,"e"); + ws=real(w(abs(imag(w))<epsr&real(w)<=0)) //points where phase is -180° + + //remove nearly singular points + ws(abs(horner(num,ws))>=epssing*abs(horner(den,ws)))=[] + if ws==[] then gm=%inf,fr=[],return,end + mingain=real(freq(h.num,h.den,%i*ws)) + else //discrete time case + if h.dt=="d" then dt=1,else dt=h.dt,end + //get z such as h(z)=h(1/z) and z=e^(%i*w*dt) + //form hh=h(z)-h(1/z) + z=poly(0,varn(h.den)); + sm=simp_mode();simp_mode(%f);hh=h-horner(h,1/z);simp_mode(sm) + //find the numerator roots + z=roots(hh.num,"e"); + z(abs(abs(z)-1)>eps1)=[]// retain only roots with modulus equal to 1 + + //remove nearly singular points + z(abs(horner(hh.num,z))>=epssing*abs(horner(hh.den,z)))=[]; + + w=log(z)/(%i*dt) + ws=real(w(abs(imag(w))<epsr)) //points where phase is -180° + if ws==[] then gm=%inf,fr=[],return,end + mingain=real(horner(h,exp(%i*ws*dt))) + end + + k=find(mingain<0) + if k==[] then gm=%inf,fr=[],return,end + mingain=abs(mingain(k)); + ws=abs(ws(k))// select positive frequency + + gm=-20*log(mingain)/log(10) //tranform into Db + [gm,k]=min(gm);ws=ws(k);//select the minimum + + fr=ws/(2*%pi) //transform in Hz +endfunction diff --git a/modules/cacsd/macros/gainplot.bin b/modules/cacsd/macros/gainplot.bin Binary files differnew file mode 100755 index 000000000..da0451488 --- /dev/null +++ b/modules/cacsd/macros/gainplot.bin diff --git a/modules/cacsd/macros/gainplot.sci b/modules/cacsd/macros/gainplot.sci new file mode 100755 index 000000000..e840fa046 --- /dev/null +++ b/modules/cacsd/macros/gainplot.sci @@ -0,0 +1,119 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge Steer +// 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 []=gainplot(varargin) + rhs=size(varargin) + + if rhs == 0 then + s=poly(0,"s"); + h1=syslin("c",(s^2+2*0.9*10*s+100)/(s^2+2*0.3*10.1*s+102.01)); + h2=syslin("c",(s^2+2*0.1*15.1*s+228.01)/(s^2+2*0.9*15*s+225)); + gainplot([h1;h2],0.01,100,.. + ["$\frac{s^2+18 s+100}{s^2+6.06 s+102.1}$"; + "$\frac{s^2+3.02 s+228.01}{s^2+27 s+225}$"]); + title("Gainplot"); + return; + end + + if type(varargin($))==10 then + comments=varargin($); + rhs=rhs-1; + else + comments=[]; + end + fname="gainplot";//for error messages + + fmax=[]; + if or(typeof(varargin(1))==["state-space" "rational"]) then + //sys,fmin,fmax [,pas] or sys,frq + refdim=1 //for error message + if rhs==1 then + [frq,repf]=repfreq(varargin(1),1d-3,1d3); + elseif rhs==2 then //sys,frq + if size(varargin(2),2)<2 then + error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"),.. + fname,2,1)); + end + [frq,repf]=repfreq(varargin(1:rhs)); + elseif or(rhs==(3:4)) then //sys,fmin,fmax [,pas] + [frq,repf]=repfreq(varargin(1:rhs)); + else + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),fname,1,5)) + end + [phi,d]=phasemag(repf); + elseif type(varargin(1))==1 then + //frq,db,phi [,comments] or frq, repf [,comments] + refdim=2 + select rhs + case 2 then //frq,repf + frq=varargin(1); + if size(frq,2)<2 then + error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"),.. + fname,1,1)) + end + if size(frq,2)<>size(varargin(2),2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),.. + fname,1,2)) + end + + [phi,d]=phasemag(varargin(2)) + case 3 then //frq,db,phi + [frq,d]=varargin(1:rhs-1) + if size(frq,2)<>size(d,2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),.. + fname,1,2)) + end + else + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),fname,2,4)) + end + else + error(msprintf(_("%s: Wrong type for input argument #%d: Linear dynamical system or row vector of floats expected.\n"),fname,1)) + end; + + frq=frq'; + d=d'; + [n,mn]=size(d); + if and(size(comments,"*")<>[0 mn]) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same number of elements expected.\n"),... + fname,refdim,rhs+1)) + end + + // + fig=gcf(); + immediate_drawing=fig.immediate_drawing; + fig.immediate_drawing="off"; + + axes = gca() ; + if size(axes.children,"*")==0 then + axes.data_bounds=[min(frq),min(d);max(frq),max(d)] + axes.x_label.text=_("Frequency (Hz)") + axes.y_label.text=_("Magnitude (dB)") + + else + axes.data_bounds=[min([min(frq),min(d)],axes.data_bounds(1,:)); + max([max(frq),max(d)],axes.data_bounds(2,:))]; + end + axes.axes_visible="on"; + axes.log_flags = "lnn" ; + axes.grid=color("lightgrey")*ones(1,3); + + if size(d,2)>1&size(frq,2)==1 then + xpolys(frq(:,ones(1,mn)),d,1:mn) + e=gce(); + else + xpolys(frq,d,1:mn) + e=gce(); + end + for i=1:size(e.children,"*") + e.children(i).display_function = "formatGainplotTip"; + end + if comments<>[] then + legend(comments) + end + fig.immediate_drawing=immediate_drawing; +endfunction diff --git a/modules/cacsd/macros/gamitg.bin b/modules/cacsd/macros/gamitg.bin Binary files differnew file mode 100755 index 000000000..a1d9e3306 --- /dev/null +++ b/modules/cacsd/macros/gamitg.bin diff --git a/modules/cacsd/macros/gamitg.sci b/modules/cacsd/macros/gamitg.sci new file mode 100755 index 000000000..4dc19bf92 --- /dev/null +++ b/modules/cacsd/macros/gamitg.sci @@ -0,0 +1,395 @@ + +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - P. Gahinet +// +// 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 [gopt]=gamitg(g,r,PREC,options) + //[gopt]=gamitg(G,r,PREC,options); + // + // On input: + // --------- + // * G contains the parameters of plant realization (syslin list) + // b = ( b1 , b2 ) , c = ( c1 ) , d = ( d11 d12) + // ( c2 ) ( d21 d22) + // * r(1) and r(2) are the dimensions of d22 (rows x columns) + // * PREC is the desired relative accuracy on the norm + // * available options are + // - 't': traces each bisection step, i.e., displays the lower + // and upper bounds and the current test point. + // + // On output: + // --------- + // * gopt: optimal Hinf gain + // + //! + // History: + // ------- + // author: P. Gahinet, INRIA + // last modification: + //**************************************************************************** + // Copyright INRIA + + 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"),"gamitg",1)) + end + if g.dt<>"c" then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Continuous time system expected.\n"),"gamitg",1)) + end + //user interface. The default values are: + // PREC=1.0e-3; options='nul'; + //************************************************ + [lhs,rhs]=argn(0); + select rhs, + case 1 then + error(msprintf(gettext("%s: Wrong number of input arguments: At least %d expected.\n"),"gamitg",2)) + case 2 then + PREC=1.0e-3; options="nul"; + case 3 then + if type(PREC)==10 then + iopt=3 + options=PREC; PREC=1.0e-3; + else + options="nul"; + end, + case 4 then + iopt=4 + end + if typeof(r)<>"constant"|~isreal(r) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real vector expected.\n"),"gamitg",2)) + end + if size(r,"*")<>2 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: %d expected.\n"),"gamitg",2,2)) + end + r=int(r); + if or(r<=0) then + error(msprintf(gettext("%s: Wrong values for input argument #%d: Elements must be positive.\n"),"gamitg",2)) + end + + if type(options)<>10|and(options<>["t","nul"]) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),"gamitg",iopt,"""t"",""nul""")) + end + if type(PREC)<>1|size(PREC,"*")<>1|~isreal(PREC)|PREC<=0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be a positive scalar.\n"),"gamitg",3)) + end + + //constants + //********* + INIT_LOW=1.0e-3; INIT_UPP=1.0e6; INFTY=10e10; + RELACCU=1.0e-10; //relative accuracy on generalized eigenvalue computations + gopt=-1; + + //parameter recovery + [a,b1,b2,c1,c2,d11,d12,d21,d22]=smga(g,r); + + //dimensions + [na,na]=size(a); twona=2*na; + [p1,m2]=size(d12), + [p2,m1]=size(d21), + + //CHECK HYPOTHESES + //**************** + + if m2 > p1 then + warning(msprintf(gettext("%s: Dimensions of %s are inadequate.\n"),"gamitg","D12")); + end + + if p2 > m1 then + warning(msprintf(gettext("%s: Dimensions of %s are inadequate.\n"),"gamitg","D21")); + end + + [u12,s12,v12]=svd(d12); s12=s12(1:m2,:); + [u21,s21,v21]=svd(d21); s21=s21(:,1:p2); + u12=u12(:,1:m2); //d12 = u12 s12 v12' with s12 square diagonal + v21=v21(:,1:p2); //d21 = u21 s21 v21' + + //rank condition on D12 and D21 + //----------------------------- + if s12(m2,m2)/s12(1,1) <= 100*%eps then + warning(msprintf(gettext("%s: %s is not full rank at the machine precision.\n"),"gamitg","D12")); + end + + if s21(p2,p2)/s21(1,1) <= 100*%eps then + warning(msprintf(gettext("%s: %s is not full rank at the machine precision.\n"),"gamitg","D21")); + end + + //(A,B2,C2) stabilizable + detectable + //------------------------------------- + noa=max(abs(a)); nob2=max(abs(b2)); noc2=max(abs(c2)); + + ns=st_ility(syslin("c",a,b2,c2),1.0e-10*max(noa,nob2)); + if ns<na then + warning(msprintf(gettext("%s: %s is nearly unstabilizable.\n"),"gamitg","(A,B2)")); + end + + nd=dt_ility(syslin("c",a,b2,c2),1.0e-10*max(noa,noc2)); + if nd>0 then + warning(msprintf(gettext("%s: %s is nearly unstabilizable.\n"),"gamitg","(C2,A)")); + end + + //Imaginary axis zeros: test the Hamiltonian spectra at gamma=infinity + //----------------------------------------------------------------- + + ah=a-b2*v12/s12*u12'*c1; bh=b2*v12; ch=u12'*c1; + hg=[ah,-bh/(s12**2)*bh';ch'*ch-c1'*c1,-ah']; + spech=spec(hg); + if min(abs(real(spech))) < 1.0e-9*max(abs(hg)) then + warning(msprintf(gettext("%s: %s has zero(s) near the imaginary axis.\n"),"gamitg","G12")); + end + + + ah=a-b1*v21/s21*u21'*c2; ch=u21'*c2; bh=b1*v21; + jg=[ah',-ch'/(s21**2)*ch;bh*bh'-b1*b1',-ah]; + specj=spec(jg); + if min(abs(real(specj))) < 1.0e-9*max(abs(jg)) then + warning(msprintf(gettext("%s: %s has zero(s) near the imaginary axis.\n"),"gamitg","G21")); + end + + //COMPUTATION OF THE LOWER BOUND SIGMA_D + //-------------------------------------- + if m2 < p1 then + sig12=norm((eye(p1,p1)-u12*u12')*d11); + else + sig12=0; + end + + if p2 < m1 then + sig21=norm(d11*(eye(m1,m1)-v21*v21')); + else + sig21=0; + end + sigd=max(sig12,sig21); + + + + + //SEARCH WINDOW INITIALIZATION + //**************************** + // Initialize the search window [lower,upper] where `lower' and `upper' + // are lower and upper bounds on the Linf norm of G. When no such + // bounds are available, the window is arbitrarily set to [INIT_LOW,INIT_UPP] + // and the variables LOW and UPP keep record of these initial values so that + // the window can be extended if necessary. + + upper=INIT_UPP; UPP=INIT_UPP; + + if sigd==0 then + lower=INIT_LOW; LOW=INIT_LOW; + else + lower=sigd; LOW=0; + end + + + + //HAMILTONIAN SETUP + //------------------ + sh22=m1+m2; + h11=[a,0*eye(a);-c1'*c1,-a']; + h12=[-b1,-b2;c1'*d11,c1'*d12]; + h21=[d11'*c1,b1';d12'*c1,b2']; + h22=eye(m1,m1); h22(sh22,sh22)=0; + + sj22=p1+p2; + j11=[a',0*eye(a);-b1*b1',-a]; + j12=[-c1',-c2';b1*d11',b1*d21'] + j21=[d11*b1',c1;d21*b1',c2]; + j22=eye(p1,p1); j22(sj22,sj22)=0; + + d1112s=[d11,d12]'*[d11,d12]; + d1121s=[d11;d21]*[d11;d21]'; + + + T_EVALH=1; //while 1, Hamiltonian spectrum of H must be tested + T_EVALJ=1; //while 1, Hamiltonian spectrum of J must be tested + T_POSX=1; //while 1, the nonnegativity of X must be tested + T_POSY=1; //while 1, the nonnegativity of Y must be tested + + + + //******************************************************** + // GAMMA ITERATION STARTS + //******************************************************** + + for iterations=1:30, //max iterations=30 + + ga=sqrt(lower*upper); //test point gamma = log middle of [lower,upper] + gs=ga*ga; + + if str_member("t",options) then + write(%io(2),[lower,ga,upper],"(''min,cur,max = '',3e20.10)"); + end + + // Search window management: + //-------------------------- + // If the gamma-iteration runs into one of the initial arbitrary bounds + // LOW or UPP, extend the search window to allow for continuation + + if ga<10*LOW then lower=LOW/10; LOW=lower; end + // expand search window toward gamma<<1 + if ga>UPP/10 then upper=UPP*10; UPP=upper; end + // expand search window toward gamma>>1 + + + + + DONE=0 + //DONE=1 indicates that the current gamma has been classified and + //the next iteration can start + + + //---------------------------------------------------------------------- + // FIRST TEST : PURE IMAGINARY EIGENVALUES IN HAMILTONIAN SPECTRUM ? + //---------------------------------------------------------------------- + + hg=h11-(h12/(gs*h22-d1112s))*h21; + + if T_EVALH==1 then + hev=spec(hg); + if min(abs(real(hev))) <= RELACCU*max(abs(hev)) then + lower=ga; DONE=1; //Hg HAS EVAL ON iR -> NEXT LOOP + if str_member("t",options) then + mprintf(gettext("%s: %s has pure imaginary eigenvalue(s).\n"),"gamitg","H"); + end + end + end + + + if DONE==0 then + jg=j11-(j12/(gs*j22-d1121s))*j21; + + if T_EVALJ==1 then + jev=spec(jg); + if min(abs(real(jev))) <= RELACCU*max(abs(jev)) then + lower=ga; DONE=1; //Jg HAS EVAL ON iR -> NEXT LOOP + if str_member("t",options) then + mprintf(gettext("%s: %s has pure imaginary eigenvalue(s).\n"),"gamitg","J"); + end + end + end + end + + + + //--------------------------------------------------------- + // SECOND TEST : NONNEGATIVITY OF THE RICCATI SOLUTIONS + //--------------------------------------------------------- + + + if DONE==0 then + + //compute orthon. bases of the negative invariant subspace of H + [uh,d]=schur(hg,"c"); + px=uh(1:na,1:na); qx=uh(na+1:twona,1:na); + + //nonnegativity test for X (or Y): + //-------------------------------- + // * if |f(i)| < RELACCU then discard this eval (this corresponds + // to ||X||-> infty and the sign is ill-defined + // * if |e(i)| < RELACCU then X is nearly singular in this direction. + // We then consider X is actually singular and that the eval can be + // discarded + // * For the remaining entries, if e(i)/f(i) < - RELACC/100 then X is + // diagnosed as indefinite. Otherwise X is nonnegative. + + if T_POSX==1 then + [e,f]=spec(qx,px); + i=1; + while i<=na, + if min(abs([e(i),f(i)])) >= RELACCU & real(e(i)/f(i)) <= 0 then + lower=ga; DONE=1; T_EVALH=0; i=na+1; + if str_member("t",options) then + mprintf(gettext("%s: %s is indefinite.\n"),"gamitg","X"); + end + else + i=i+1; + end + end + end + end + + + + if DONE==0 then + + //compute orthon. bases of the negative inv. subspace of J + [uj,d]=schur(jg,"c"); + py=uj(1:na,1:na); qy=uj(na+1:twona,1:na); + + if T_POSY==1 then + [e,f]=spec(qy,py); + i=1; + while i<=na, + if min(abs([e(i),f(i)])) >= RELACCU & real(e(i)/f(i)) <= 0 then + lower=ga; DONE=1; T_EVALJ=0; i=na+1; + if str_member("t",options) then + mprintf(gettext("%s: %s is indefinite.\n"),"gamitg","Y");end; + else + i=i+1; + end + end + end + end + + + //-------------------------------------------------------------- + // THIRD TEST : COMPARE THE SPECTRAL RADIUS OF XY WITH gamma**2 + //-------------------------------------------------------------- + + + if DONE==0 then + + [e,f]=spec(qy'*qx,py'*px); + if max(real(e-gs*f)) <= 0 then + upper=ga; + if str_member("t",options) then + write(%io(2),"rho(XY) <= gamma**2"); end + else + lower=ga; T_POSX=0; T_POSY=0; T_EVALH=0; T_EVALJ=0; + if str_member("t",options) then + write(%io(2),"rho(XY) > gamma**2"); end + end + end + + + + //------------------ + // TERMINATION TESTS + //------------------ + + if lower > INFTY then + mprintf(gettext("%s: Controllable & observable mode(s) of %s near the imaginary axis.\n"),"gamitg","A"); + gopt=lower; + return; + else + if upper < 1.0e-10 then + gopt=upper; + mprintf(gettext("%s: All modes of %s are nearly nonminimal so that %s is almost %d.\n"),"gamitg","A","|| G ||",0); + return; + else + if 1-lower/upper < PREC, + gopt=sqrt(lower*upper); + return; + end, + end, + end + + + end//end while + + gopt=sqrt(lower*upper); + +endfunction +function [bool]=str_member(c,s) + //********************** + // tests whether the character c occurs in the string s + // returns %T (true) if it does, %F (false) otherwise. + + for i=1:length(s), + if part(s,i)==c then bool=%t; return; end + end + bool=%f; +endfunction diff --git a/modules/cacsd/macros/gcare.bin b/modules/cacsd/macros/gcare.bin Binary files differnew file mode 100755 index 000000000..7272e2375 --- /dev/null +++ b/modules/cacsd/macros/gcare.bin diff --git a/modules/cacsd/macros/gcare.sci b/modules/cacsd/macros/gcare.sci new file mode 100755 index 000000000..50502b5b5 --- /dev/null +++ b/modules/cacsd/macros/gcare.sci @@ -0,0 +1,30 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [X,F]=gcare(Sl) + //[X,F]=gcare(Sl) + //Generalized Control Algebraic Riccati Equation + //X = solution , F = gain + //! + if typeof(Sl)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"gcare",1)) + end + if Sl.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"gcare",1)) + end + + [A,B,C,D]=abcd(Sl); + S=eye()+D'*D;R=eye()+D*D'; + Si=inv(S); + Ar=A-B*Si*D'*C; + H=[Ar,-B*Si*B'; + -C'*inv(R)*C,-Ar']; + X=ric_desc(H); + F=-Si*(D'*C+B'*X) +endfunction diff --git a/modules/cacsd/macros/gfare.bin b/modules/cacsd/macros/gfare.bin Binary files differnew file mode 100755 index 000000000..ee478f102 --- /dev/null +++ b/modules/cacsd/macros/gfare.bin diff --git a/modules/cacsd/macros/gfare.sci b/modules/cacsd/macros/gfare.sci new file mode 100755 index 000000000..a3090d9ce --- /dev/null +++ b/modules/cacsd/macros/gfare.sci @@ -0,0 +1,35 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [Z,H]=gfare(Sl) + //[Z,H]=gfare(Sl) + //Generalized Filter Algebraic Riccati Equation + //X = solution , F = gain + //! + if argn(2)<1 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected.\n"),.. + "gfare",1)) + end + + if typeof(Sl)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"gfare",1)) + end + if Sl.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"gfare",1)) + end + + [A,B,C,D]=abcd(Sl); + S=eye()+D'*D;R=eye()+D*D'; + Si=inv(S);Ri=inv(R); + Ar=A-B*Si*D'*C; + H=[Ar',-C'*Ri*C; + -B*Si*B',-Ar]; + Z=ric_desc(H); + H=-(B*D'+Z*C')*Ri +endfunction diff --git a/modules/cacsd/macros/gfrancis.bin b/modules/cacsd/macros/gfrancis.bin Binary files differnew file mode 100755 index 000000000..084bf5ea4 --- /dev/null +++ b/modules/cacsd/macros/gfrancis.bin diff --git a/modules/cacsd/macros/gfrancis.sci b/modules/cacsd/macros/gfrancis.sci new file mode 100755 index 000000000..d8b916306 --- /dev/null +++ b/modules/cacsd/macros/gfrancis.sci @@ -0,0 +1,76 @@ +// 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 [L,M,T]= gfrancis(Plant,Model); + // This function computes an optimal model matching + // controller for the linear plant + // x'= F*x + G*u + // y = H*x + J*u + // and the linear model + // xm'= A*xm + B*um + // ym = C*xm + D*um + // The dimensions of x,u,y are n,m,p and those of xm,um,ym are + // nn,mm,pp and pp=p. + // The goal is for the plant to track the model + // e = y - ym ---> 0 + // while keeping stable the state x(t) of the plant. To accomplish + // this, we use feedforward and feedback + // u = L*xm + M*um + K*(x-T*xm) = [K , L-K*T] *(x,xm) + M*um + // to drive the combined system to the closed loop invariant subspace + // x = T*xm + // where e = 0. + // The matrices T,L,M satisfy generalized Francis equations + // F*T + G*L = T*A + // H*T + J*L = C + // G*M = T*B + // J*M = D + // The matrix K is chosen as stabilizing the pair (F,G) i.e + // F+G*K is stable. + // For more information on this approach, see + // Krener, A. J., Optimal model matching controllers for linear + // and nonlinear systems, Proceedings of NOLCOS, Bordeaux, 1992. + if typeof(Plant)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"gfrancis",1)) + end + if Plant.dt<>"c" then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Continuous time system expected.\n"),"gfrancis",1)) + end + if typeof(Model)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"gfrancis",2)) + end + if Model.dt<>"c" then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Continuous time system expected.\n"),"gfrancis",2)) + end + + [F,G,H,J]=abcd(Plant); + [A,B,C,D]=abcd(Model); + [nf,nf]=size(F);[ny,nu]=size(J); + [na,na]=size(A);[lc,num]=size(D); + Ia=eye(na,na);Inf=eye(nf,nf);Iu=eye(num,num); + Mat=[Ia.*.F-A'.*.Inf, Ia.*.G, zeros(nf*na,nu*num); + Ia.*.H , Ia.*.J, zeros(ny*na,nu*num); + -B'.*.Inf, zeros(nf*num,nu*na), Iu.*.G; + zeros(ny*num,nf*na),zeros(ny*num,nu*na),Iu.*.J]; + + rhs=[zeros(nf*na,1); + matrix(C,size(C,"*"),1); + zeros(nf*num,1); + matrix(D,size(D,"*"),1)]; + TLM=pinv(Mat)*rhs; + T=TLM(1:nf*na);T=matrix(T,nf,na); + L=TLM(nf*na+1:nf*na+nu*na);L=matrix(L,nu,na); + M=TLM(nf*na+nu*na+1:nf*na+nu*na+nu*num);M=matrix(M,nu,num); + Wplant=[F,G;H,J]; + Wmodel=[A,B;C,D]; + //check + err=norm(Wplant*[T,zeros(nf,num); + L,M]-[T,zeros(nf,lc); + zeros(lc,na),eye(lc,lc)]*Wmodel,1); + if err > 1.d-5 then warning(msprintf(gettext("%s: Francis equations not satisfied.\n"),"gfrancis"));end +endfunction diff --git a/modules/cacsd/macros/gtild.bin b/modules/cacsd/macros/gtild.bin Binary files differnew file mode 100755 index 000000000..79f80c0d0 --- /dev/null +++ b/modules/cacsd/macros/gtild.bin diff --git a/modules/cacsd/macros/gtild.sci b/modules/cacsd/macros/gtild.sci new file mode 100755 index 000000000..037a532e9 --- /dev/null +++ b/modules/cacsd/macros/gtild.sci @@ -0,0 +1,111 @@ +// 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 Gt=gtild(G,flag) + // input: + // G(s): a polynomial matrix or a rational matrix + // represented in state-space or in transfer form + // + // Gt=gtild(G) or Gt=gtild(G,'c') + // returns Gt = G(-s)' (in transfer form or in state-space) + // for continuous time system G + //or + // Gt=gtild(G) or Gt=gtild(G,'d') + // returns Gt = z^n * G(1/z)' (n = maximum degree of G) + // for discrete-time matrix polynomials + //! + + [lhs,rhs]=argn(0) + if rhs==1 then + if typeof(G)=="rational" + flag=G(4) + elseif typeof(G)=="state-space" + flag=G(7) + elseif typeof(G)=="polynomial" + flag=[] + end + end + + select typeof(G) + case "polynomial" + if flag=="c" + Gt=cp_tilde(G);return; + elseif flag=="d" + Gt=dp_tilde(G);return; + elseif flag==[] + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),.. + "gtild",2,"''c'', ''d''")); + end + + case "rational" + v=varn([G(2),G(3)]);s=poly(0,v); + if flag=="c" + Gt=horner(G',-s);return; + elseif flag=="d" + Gt=horner(G',1/s);return; + elseif flag==[] + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),.. + "gtild",2,"''c'', ''d''")); + end + + case "state-space" + if flag==[] then dom=G(7);else dom=flag;end + [A,B,C,D]=abcd(G); + if dom=="c" then + if typeof(D)=="polynomial" + Dp=horner(D,-poly(0,varn(D))); + Gt=syslin(dom,-A',-C',B',Dp');return; + elseif typeof(D)=="constant" + Gt=syslin(dom,-A',-C',B',D');return + end + elseif dom=="d" + if typeof(G(5))=="polynomial" + Dp=horner(D,1/poly(0,varn(D))); + Dp=tf2ss(Dp); + [A,B,C,D]=abcd(G'); + w=tlist(["des","A","B","C","D","E"],eye(A),B,C,0*C*B,A); + z=poly(0,"z");zss=-tf2ss(z);zss(7)="d"; + Gt=zss*des2ss(w)+Dp'; + elseif typeof(G(5))=="constant" + z=poly(0,"z");zss=-tf2ss(z);zss(7)="d"; + [A,B,C,D]=abcd(G'); //lazy way for transposition... + w=tlist(["des","A","B","C","D","E"],eye(A),B,C,0*D,A); + Gt=zss*des2ss(w)+D; //-z*C*inv(I-z*A)*B + D + end + end + // + case "constant" + Gt=G';return; + end + + + +endfunction +function mpt=dp_tilde(mp) + //mp(z) = polynomial matrix + // mpt(i,j)= z^n*conj(mp(j,i))(1/z) + [m,n]=size(mp),z=varn(mp) + //max degree + nmax=max(degree(mp)); + for i=1:m + for j=1:n + mpt(j,i)=poly(coeff(conj(mp(i,j)),nmax:-1:0),z,"c") + end + end + +endfunction +function mpt=cp_tilde(mp) + //mp(s) = polynomial matrix + // mpt(i,j)= conj(mp(j,i))(s) + s=poly(0,varn(mp)); + pr=real(mp);pi=imag(mp); + mpt=horner(pr',-s); + if pi==0*s then return;end + mpt=mpt+%i*horner(pi',-s); +endfunction diff --git a/modules/cacsd/macros/h2norm.bin b/modules/cacsd/macros/h2norm.bin Binary files differnew file mode 100755 index 000000000..73af50efc --- /dev/null +++ b/modules/cacsd/macros/h2norm.bin diff --git a/modules/cacsd/macros/h2norm.sci b/modules/cacsd/macros/h2norm.sci new file mode 100755 index 000000000..6a0483f79 --- /dev/null +++ b/modules/cacsd/macros/h2norm.sci @@ -0,0 +1,77 @@ +// 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 [nh]=h2norm(g,tol) + // + // /+00 + // 2 | * + // |g| =1/(2*%pi).|trace[g(jw).g(jw)]dw + // 2 | + // /-00 + if argn(2)<1 then + error(msprintf(gettext("%s: Wrong number of input argument(s): At least %d expected.\n"),.. + "h2norm",1)) + end + + if type(g)==1,if norm(g)==0,nh=0,return,end,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"),"h2norm",1)) + end + if g.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"h2norm",1)) + end + + [lhs,rhs]=argn(0), + if rhs==1 then + tol=1000*%eps, + else + if type(tol)<>1|size(tol,"*")<>1 then + error(msprintf(gettext("%s: Wrong type for input argument: Scalar expected.\n"),"h2norm",2)) + end + if ~isreal(tol)|tol<=0 then + error(msprintf(gettext( "%s: Input argument #%d must be strictly positive.\n"),"h2norm",2)) + end + end; + select typeof(g) + case "state-space" then + if norm(g.D)>0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Proper system expected.\n"),"h2norm",1)), + end; + sp=spec(g.A), + if max(real(sp))>=-tol then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Stable system expected.\n"),"h2norm",1)), + end, + w=obs_gram(g.A,g.C,"c"), + nh=abs(sqrt(sum(diag(g.B'*w*g.B)))),return, + case "rational" then + num=g.num; + den=g.den; + s=poly(0,varn(den)), + [t1,t2]=size(num), + for i=1:t1, + for j=1:t2, + n=num(i,j),d=den(i,j), + if coeff(n)==0 then + nh(i,j)=0, + else + if degree(n)>=degree(d) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Proper system expected.\n"),"h2norm",1)), + end + pol=roots(d), + if max(real(pol))>-tol then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Stable system expected.\n"),"h2norm",1)), + end, + nt=horner(n,-s),dt=horner(d,-s), + nh(i,j)=residu(n*nt,d,dt), + end, + end + end + nh=sqrt(sum(nh)),return, + end +endfunction diff --git a/modules/cacsd/macros/h_cl.bin b/modules/cacsd/macros/h_cl.bin Binary files differnew file mode 100755 index 000000000..743da92cf --- /dev/null +++ b/modules/cacsd/macros/h_cl.bin diff --git a/modules/cacsd/macros/h_cl.sci b/modules/cacsd/macros/h_cl.sci new file mode 100755 index 000000000..b18ff0b3f --- /dev/null +++ b/modules/cacsd/macros/h_cl.sci @@ -0,0 +1,60 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// 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 Aclosed=h_cl(P,r,K) + //[Aclosed]=h_cl(P,r,K) + //Given the standard plant P (with r=size(P22)) and the controller + //K (computed e.g. by h_inf) this macro returns the closed loop + //matrix Aclosed whose poles allows to checks the internal stability + //of the closed loop system. + //Aclosed is the A matrix of [I -P22;-K I]^-1; + //! + + if and(typeof(P)<>["rational","state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"h_cl",1)) + end + + if typeof(P)=="rational" then P=tf2ss(P);end + [LHS,RHS]=argn(0); + if RHS==2 then //h_cl(P,K) + K=r;[A,B2,C2,D22]=abcd(P); + iK=2 + elseif RHS==3 then //h_cl(P,r,K) + if typeof(r)<>"constant"|~isreal(r) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real vector expected.\n"),"h_cl",2)) + end + if size(r,"*")<>2 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: %d expected.\n"),"h_cl",2,2)) + end + r=int(r); + if or(r<=0) then + error(msprintf(gettext("%s: Wrong values for input argument #%d: Elements must be positive.\n"),"h_cl",2,2)) + end + + [A,B1,B2,C1,C2,D11,D12,D21,D22]=smga(P,r); + iK=3 + end + if and(typeof(K)<>["rational","state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"h_cl",iK)) + end + + if typeof(K)=="rational" then K=tf2ss(K);end + + [Ac,Bc,Cc,Dc]=abcd(K); + [n,pp]=size(B2);[ndc1,ndc2]=size(Dc);[nd1,nd2]=size(D22); + [m,q]=size(Bc); + Bw=[B2,0*ones(n,ndc2); + 0*ones(m,pp),Bc]; + [n1,m2]=size(Cc); + [n2,m1]=size(C2); + Cw=[0*ones(ndc1,m1),Cc; + C2,0*ones(n2,m2)]; + Aclosed=[A, 0*ones(n,m); + 0*ones(m,n),Ac]+... + Bw*inv([eye(ndc1,ndc1),-Dc;-D22,eye(nd1,nd1)])*Cw; +endfunction diff --git a/modules/cacsd/macros/h_inf.bin b/modules/cacsd/macros/h_inf.bin Binary files differnew file mode 100755 index 000000000..97368b716 --- /dev/null +++ b/modules/cacsd/macros/h_inf.bin diff --git a/modules/cacsd/macros/h_inf.sci b/modules/cacsd/macros/h_inf.sci new file mode 100755 index 000000000..d3ed7048b --- /dev/null +++ b/modules/cacsd/macros/h_inf.sci @@ -0,0 +1,567 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [Sk,rk,mu]=h_inf(P,r,mumin,mumax,nmax) + // H-infinity optimal control for the continuous-time plant P + // P is the plant (linear system)given in state-space form or in transfer form, + // e.g. P=syslin('c',A,B,C,D) with A,B,C,D = scalar matrices + // or P=syslin('c',H) with H a transfer matrix. + // r = size of the P22 plant i.e. 2-vector [#outputs,#inputs]; + // mumin,mumax = bounds on mu with mu=1/gama^2; (mumin=0 usually) + // nmax = maximum number of iterations in the gama-iteration. + // Two possible calling sequences: + // [Sk,mu]=h_inf(P,r,mumin,mumax,nmax) returns mu and the central controller + // Sk in the same representation as P. (All calculations being done in state + // space). + // [Sk,rk,mu]=h_inf(P,r,mumin,mumax,nmax) returns mu + // and the parametrization of all stabilizing controllers: + // a stabilizing controller K is obtained by K=Fl(Sk,r,PHI) where + // PHI is a linear system with dimensions r' and satisfy h_norm(PHI) < gama. + // rk (=r) is the size of the Sk22 block and mu = 1/gama^2 after nmax + // iterations. + //! + // + // Initialization : Uci and Yci normalize P + // mu_inf upper bound on mu = gama^-2 + //P2 = normalized P. + // + if argn(2)<>5 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected.\n"),"h_inf",5)) + end + + if and(typeof(P)<>["rational","state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"h_inf",1)) + end + if P.dt<>"c" then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Continuous time system expected.\n"),"h_inf",1)) + end + if typeof(r)<>"constant"|~isreal(r) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real vector expected.\n"),"h_inf",2)) + end + if size(r,"*")<>2 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: %d expected.\n"),"h_inf",2,2)) + end + r=int(r); + if or(r<=0) then + error(msprintf(gettext("%s: Wrong values for input argument #%d: Elements must be positive.\n"),"h_inf",2)) + end + + + if typeof(mumin)<>"constant"|~isreal(mumin) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real vector expected.\n"),"h_inf",3)) + end + if size(mumin,"*")<>1 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Scalar expected.\n"),"h_inf",3)) + end + if or(mumin<0) then + error(msprintf(gettext("%s: Wrong values for input argument #%d: Elements must be positive.\n"),"h_inf",3)) + end + + + if typeof(mumax)<>"constant"|~isreal(mumax) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real vector expected.\n"),"h_inf",4)) + end + if size(mumax,"*")<>1 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Scalar expected.\n"),"h_inf",4)) + end + if mumax<0 then + error(msprintf(gettext("%s: Wrong values for input argument #%d: Elements must be positive.\n"),"h_inf",4)) + end + if typeof(nmax)<>"constant"|~isreal(nmax) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real vector expected.\n"),"h_inf",5)) + end + + if nmax<>int(nmax)|nmax<=0 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A positive integer expected.\n"),"h_inf",5)) + end + [P2,mu_inf,Uci,Yci,D22]=h_init(P,r,%t) + //if mu_inf < mumax then write(%io(2),mu_inf,'(3x,''romax too big: max romax= '',f10.5)');end + mumax=min(mu_inf,mumax) + // + // Gama-iteration P6 = transformed P2 with D11 removed + [P6,Finf,mu,Uc#i,Yc#i]=h_iter(P2,r,mumin,mumax,nmax) + if mu==0 then + warning(msprintf(_("%s : No feasible ro in bounds [%g %g]\n"),"h_inf",mumin,mumax)); + rk=[];Sk=[]; + return, + end + // + // Optimal controller for P6 + [Sk,polesH,polesJ]=h_contr(P6,r,1/mu,Uc#i,Yc#i); + [E,Ak,Bk1,Bk2,Ck1,Ck2,Dk11,Dk12,Dk21,Dk22]=Sk(:); + // Add the optimal controller at infinity + if norm(Finf,1) <> 0 then Dk11=Dk11+Finf;end + // Back-normalization of the controller + Bk1=Bk1*Yci; + Ck1=Uci*Ck1; + Dk11=Uci*Dk11*Yci; + Dk12=Uci*Dk12; + Dk21=Dk21*Yci; + //Convert to descriptor form: + Sk=des2ss(Ak,[Bk1,Bk2],[Ck1;Ck2],[Dk11,Dk12;Dk21,Dk22],E); + if argn(1)<3 then + Sk=Sk(1:r(2),1:r(1));rk=mu; + // Case D22 different from zero + if norm(coeff(D22),1) <> 0 then Sk=Sk/.D22;end + else + rk=r; + end + // Sk in transfer representation if P is. + if typeof(P)=="rational" then Sk=ss2tf(Sk);end; +endfunction + +function [P2,mu_inf,Uci,Yci,D22]=h_init(P,r,info) + //****************************** + // Initialization of the standard plant + // P = standard plant; r=size of P22 (1X2 vector) + // P2 = normalized plant + // gama_inf :lower bound on gama + // + // [C1 D12]'*[C1 D12] = Q = [Q1 S;S' Q2] + // [B1;D21] *[B1;D21]'= R = [R1 L';L R2] + //! + + P1=P(1); + if P1(1)=="r" then P=tf2ss(P);end + [A,B1,B2,C1,C2,D11,D12,D21,D22]=smga(P,r); + [na,na]=size(A); + [p1,m2]=size(D12), + [p2,m1]=size(D21), + //Useful indexes + l1=1:p1-m2;k1=1:m1-p2; + l2=1+p1-m2:p1;k2=1+m1-p2:m1; + + //**************Check assumptions****************** + + //Stabilizability/detectability of P22 ? + + P22=syslin("c",A,B2,C2); + + [ns,Us,St]=st_ility(P22,1.d-10) + + if ns<>na then + warning(msprintf(gettext("%s: %s is not stabilizable.\n"),"h_inf","P22")); + end + if ns==na & info then + mprintf(gettext("%s: %s is stabilizable.\n"),"h_inf","P22"); + end + + [nd,Ud,Sd]=dt_ility(P22,1.d-10) + + if nd <> 0 then + warning(msprintf(gettext("%s: %s is not detectable.\n"),"h_inf","P22")); + end + if nd==0 & info then + mprintf(gettext("%s: %s is detectable.\n"),"h_inf","P22"); + end + + // rank P21=[A,B2,C1,D12] = m2 ? + P12=syslin("c",A,B2,C1,D12); + [nt,dt]=trzeros(P12),rzt=real(nt./dt), + if size(nt,"*") > 0 then + if min(abs(rzt)) < sqrt(%eps) then + warning(msprintf(gettext("%s: %s has a zero on/close the imaginary axis.\n"),"h_inf","P12")), + end, + end, + + // rank P21=[A,B1,C2,D21] = p2 ? + P21=syslin("c",A,B1,C2,D21); + [nt,dt]=trzeros(P21),rzt=real(nt./dt), + if size(nt,"*")>0 then + if min(abs(rzt)) < sqrt(%eps) then + warning(msprintf(gettext("%s: %s has a zero on/close the imaginary axis.\n"),"h_inf","P21")), + end, + end, + + //***********************end*************************** + + //Row compression of D12 (bottom) + [T1,r1]=rowcomp(D12), + if r1<>m2 then + error(msprintf(gettext("%s: Wrong values for input argument #%d: %s is not full rank.\n"),"h_inf",1,"D12")); + end, + T1=[T1(r1+1:p1,:);T1(1:r1,:)], + D12=T1*D12, + //Column compression of D21 (right) + [S1,r2]=colcomp(D21), + if r2<>p2 then + error(msprintf(gettext("%s: Wrong values for input argument #%d: %s is not full rank.\n"),"h_inf",1,"D21")); + end, + D21=D21*S1, + //Updating + B1=B1*S1,C1=T1*C1, + D11=T1*D11*S1, + + // Scaling on U and Y + Uc=D12(l2,:); + Uci=inv(Uc); + B2=B2*Uci; + D12=D12*Uci; + + Yc=D21(:,k2) + Yci=inv(Yc); + C2=Yci*C2; + D21=Yci*D21; + + //P2=[A,B1,B2,C1,C2,D11,D12,D21,D22] with D12 and D21 scaled; + + //Initialization + + //Solve H-infinity problem at infinity + + D1111=D11(l1,k1), + D1112=D11(l1,k2), + D1121=D11(l2,k1), + D1122=D11(l2,k2), + + M11=[D1111,D1112];M22=[D1111',D1121']; + g1=-1;g2=-1; + if M11<>[] then g1=norm(M11);end + if M22<>[] then g2=norm(M22);end + + gama_inf=max(g1,g2); + if gama_inf==0 then mu_inf=1/%eps/%eps, else mu_inf=1/(gama_inf*gama_inf);end + + P2=syslin("c",A,[B1,B2],[C1;C2],[D11,D12;D21,0*D22]); + + //P2 = standard plant with D22=0 and D12,D21 normalized; + + +endfunction +function [P6ad,Finfad,muad,Uc#iad,Yc#iad]=h_iter(P2,r,mumin,mumax,nmax) + niter=0;muad=0;P6ad=[]; Finfad=[];Uc#iad=[];Yc#iad=[]; + while niter < nmax + niter=niter+1; + mu=(mumin+mumax)/2; + [P6,Finf,tv,Uc#i,Yc#i]=h_test(P2,r,mu) + + test=max(tv) + + if test > 0 then + mumax=mu + else + mumin=mu,muad=mu;P6ad=P6;Finfad=Finf;Uc#iad=Uc#i;Yc#iad=Yc#i; + end + + end //while +endfunction + +function [P6,Kinf,tv,Uc#i,Yc#i]=h_test(P2,r,mu) + //**************************** + //To test if mu is feasable for the plant P2 : + //mu is feasible for P2 iff the three components of + //tv are negative + //! + // + // [C1 D12]*[C1 D12]'=Q=[Q1 S;S' Q2] + // [B1;D21]*[B1;D21]'=R=[R1 L';L R2] + tv=[1,1,1]; + [A,B1,B2,C1,C2,D11,D12,D21,D22]=smga(P2,r); + [p1,m2]=size(D12), + [p2,m1]=size(D21), + //Useful indexes + l1=1:p1-m2;k1=1:m1-p2; + l2=1+p1-m2:p1;k2=1+m1-p2:m1; + // + + D1111=D11(l1,k1), + D1112=D11(l1,k2), + D1121=D11(l2,k1), + D1122=D11(l2,k2), + + if mu==0 then mu=%eps*%eps;end + mu1=1/mu; + gama=1/sqrt(mu); + gam2=1/(gama*gama); + + err=(m1-p2)*(p1-m2); + + if err==0 then + Kinf=-D1122 + else + Kinf=-(D1122+D1121*inv(mu1*eye()-D1111'*D1111)*D1111'*D1112); + end + + //Kinf=admissible controller for mu + + A=A+B2*Kinf*C2; + B1=B1+B2*Kinf*D21; + C1=C1+D12*Kinf*C2; + D11=D11+D12*Kinf*D21; + + if norm(D11) >= gama then + P6=[]; Kinf=[];Uc#i=[];Yc#i=[]; + error(msprintf(gettext("%s: gamma too small.\n"),"h_inf")); + end + + //P3=list(A,B1,B2,C1,C2,D11,D12,D21,D22) with norm(D11) < gama. + + Teta11=gam2*D11; + Teta22=gam2*D11'; + W12=eye()-gam2*D11*D11'; + W21=eye()-gam2*D11'*D11; + Teta12=(1/gama)*sqrtm(0.5*(W12+W12')); + Teta21=-(1/gama)*sqrtm(0.5*(W21+W21')); + + //Teta*Teta'=(1/gama*gama)*eye() + + M=inv(eye()-D11*Teta22); + N=inv(eye()-Teta22*D11); + + A=A+B1*Teta22*M*C1; + + B2=B2+B1*Teta22*M*D12; + B1=B1*N*Teta21; + + C2=C2+D21*Teta22*M*C1; + C1=Teta12*M*C1; + + D11=0*D11; //By construction... + + D22#=D22+D21*Teta22*M*D12; + + D12=Teta12*M*D12; + D21=D21*N*Teta21; + + //P4 =syslin('c',A,[B1,B2],[C1;C2],[D11,D12;D21,D22] + // with D11=0; P4=Fl(Teta,size(D11'),P3,r); + + D22=0*D22#; + + //P5 = [A,[B1,B2],[C1;C2],[D11,D12;D21,D22] with D11=0 and D22=0; + + //Row compression of D12 + [T1,r1]=rowcomp(D12); + if r1<>m2 then + error(msprintf(gettext("%s: Wrong values for input argument #%d: %s is not full rank.\n"),"h_inf",1,"D12")); + end + T1=[T1(r1+1:p1,:);T1(1:r1,:)], + D12=T1*D12, + //Column compression of D21 + [S1,r2]=colcomp(D21), + if r2<>p2 then + error(msprintf(gettext("%s: Wrong values for input argument #%d: %s is not full rank.\n"),"h_inf",1,"D21")); + end, + D21=D21*S1, + //Updating + B1=B1*S1,C1=T1*C1, + D11=T1*D11*S1, + // Scaling on U and Y + Uc#=D12(l2,:); + Uc#i=inv(Uc#); + B2=B2*Uc#i; + D12=D12*Uc#i; + + Yc#=D21(:,k2) + Yc#i=inv(Yc#); + C2=Yc#i*C2; + D21=Yc#i*D21; + + //P6=[A,B1,B2,C1,C2,D11,D12,D21,D22] with D11=0,D22=0;D12 and D21 scaled. + //Standard assumptions now satisfied + + //P6=[A,B1,B2,C1,C2,D11,D12,D21,D22]; + + // Test of mu for P6 <=> Test of mu^-1 for P2 + //Optimal controller : + indic=0; + + mu_test=1/mu; + + R1=B1*B1'; + S=D12'*C1; + C1#=(eye()-D12*D12')*C1; + Ax=A-B2*S; + Qx=-C1#'*C1#; + + Rx=mu_test*R1-B2*B2'; + H=[Ax Rx; + Qx -Ax']; + + dx=min(abs(real(spec(H)))); + //write(%io(2),dx); + if dx < 1.d-9 then + mprintf(gettext("%s: An eigenvalue of %s (controller) is close to Imaginary axis.\n"),"h_inf","H"); + write(%io(2),dx); + indic=1;test=1; + end + if indic ==0 then + [X1,X2,errx]=ric_desc(H); + if errx > 1.d-4 then + mprintf(gettext("%s: Riccati solution inaccurate: equation error = %g.\n"),"h_inf",errx); + end + //Optimal observer : + + Q1=C1'*C1; + L=B1*D21'; + B1#=B1*(eye()-D21'*D21); + Ay=A-L*C2; + Qy=-B1#*B1#'; + + Ry=mu_test*Q1-C2'*C2; + + J=[Ay' Ry; + Qy -Ay]; + dy=min(abs(real(spec(J)))); + //write(%io(2),dy); + if dy < 1.d-9 then + mprintf(gettext("%s: An eigenvalue of %s (observer) is close to Imaginary axis.\n"+.. + "The distance to the imaginary axis is less than %g "),"h_inf","J",1.d-9); + write(%io(2),dy); + indic=1 ;test=1; + end + if indic==0 then + [Y1,Y2,erry]=ric_desc(J); + if erry > 1.d-4 then + mprintf(gettext("%s: Riccati solution inaccurate: equation error = %g.\n"),"h_inf",erry); + end + //Tests + // + // E=(Y2'*X2-mu*Y1'*X1); + // write(%io(2),min(svd(E)),'(5x,''min(svd(E)) = '',f10.2)') + [al1,be1]=spec(A*X2 -B2*(S*X2 +B2'*X1 ),X2); + [al2,be2]=spec(Y2'*A-(Y2'*L+Y1'*C2')*C2,Y2'); + [al3,be3]=spec(mu_test*Y1'*X1,Y2'*X2); + + //Here division by zero may appear... + //If such division appear try to uncomment the 3 following lines: + w1=find(be1==0);be1(w1)=%eps*ones(be1(w1)); + w2=find(be2==0);be2(w2)=%eps*ones(be2(w2)); + w3=find(be3==0);be3(w3)=%eps*ones(be3(w3)); + + test1=max(real(al1./be1)); + test2=max(real(al2./be2)); + test3=max(real(al3./be3))-1; + tv =[test1,test2,test3] + end + end + + //write(%io(2),1/sqrt(mu),'(10x,'' Try gama = '',f18.10)'); + [answer,no]=max(tv); + //if exists('tv')==1 then write(%io(2),[tv,max(tv)],'(4f15.10)');end + comm1=_("Unfeasible (Hx hamiltonian)") + comm2=_("Unfeasible (Hy hamiltonian)") + comm3=_("Unfeasible (Hy hamiltonian)") + if exists("tv")==1 then + if answer>0 then + // @TODO This stuff should be localized... To bored to understand it for now. + select no + case 1 then + fmt="('' gama = '',f18.10,'' "+_("Unfeasible (Hx hamiltonian)")+" test = '',e15.5)" + case 2 then + fmt="('' gama = '',f18.10,'' "+_("Unfeasible (Hy hamiltonian)")+" test = '',e15.5)" + case 3 then + fmt="('' gama = '',f18.10,'' "+_("Unfeasible (spectral radius)")+" test = '',e15.5)" + else + fmt="('' gama = '',f18.10,'' ok ) test = '',e15.5)" + end; + write(%io(2),[1/sqrt(mu),answer],fmt); + end + end + P6=syslin("c",A,[B1,B2],[C1;C2],[D11,D12;D21,D22]) +endfunction + +function [Sk,polesH,polesJ]=h_contr(P,r,mu,U2i,Y2i) + // **************************** + // Computation of the optimal controller Sk for a standard + // plant which satisfies the assumption D11=0 + // + // F.D. + //! + // [C1 D12]*[C1 D12]'=Q=[Q1 S;S' Q2] + // [B1;D21]*[B1;D21]'=R=[R1 L';L R2] + // + + [A,B1,B2,C1,C2,D11,D12,D21,D22]=smga(P,r); + if norm(D11,1) > %eps then + error("D11 <> 0"), + end + + [p2,m1]=size(D21), + [p1,m2]=size(D12), + l1=1:p1-m2;k1=1:m1-p2; + l2=1+p1-m2:p1;k2=1+m1-p2:m1; + + //Initialization : constants + + R1=B1*B1'; + S=D12'*C1; + C1#=(eye()-D12*D12')*C1; + Ax=A-B2*S; + Qx=-C1#'*C1#; + + Q1=C1'*C1; + L=B1*D21'; + B1#=B1*(eye()-D21'*D21); + Ay=A-L*C2; + Qy=-B1#*B1#'; + + //mu-dependent part + + //Optimal controller + + Rx=mu*R1-B2*B2'; + + H=[Ax Rx; + Qx -Ax']; + polesH=spec(H); + dx=min(abs(real(polesH))); + //write(%io(2),dx); + if dx < 1.d-6 then + mprintf(gettext("%s: An eigenvalue of %s (controller) is close to Imaginary axis.\n"),"h_inf","H"); + + end + [X1,X2,errx]=ric_desc(H); + if errx > 1.d-4 then + mprintf(gettext("%s: Riccati solution inaccurate: equation error = %g.\n"),"h_inf",errx); + end + + //Optimal observer : + + Ry=mu*Q1-C2'*C2; + + J=[Ay' Ry; + Qy -Ay]; + polesJ=spec(J); + dy=min(abs(real(polesJ))); + //write(%io(2),dy); + if dy < 1.d-6 then + mprintf(gettext("%s: An eigenvalue of %s (observer) is close to Imaginary axis.\n"),"h_inf","J"); + end + [Y1,Y2,erry]=ric_desc(J); + if erry > 1.d-4 then + mprintf(gettext("%s: Riccati solution inaccurate: equation error = %g.\n"),"h_inf",erry); + end + + //Controller in descriptor form + + E=(Y2'*X2-mu*Y1'*X1); + A#=A-B2*S-L*C2; + Ak=Y2'*A#*X2+mu*Y1'*A#'*X1-Y2'*(mu*Qy+B2*B2')*X1-Y1'*(mu*Qx+C2'*C2)*X2; + Bk1=(Y2'*L+Y1'*C2'); + Ck1=-(S*X2+B2'*X1); + + Bk2=Y2'*B2+Y1'*S' + Ck2=-(C2*X2+L'*X1) + + Dk11=0*Ck1*Bk1; + Dk22=0*Ck2*Bk2; + Dk12=eye(Ck1*Bk2); + Dk21=eye(Ck2*Bk1); + + //Scaling back + + Bk1=Bk1*Y2i; + Ck1=U2i*Ck1; + Dk21=Dk21*Y2i; + Dk12=U2i*Dk12; + // Dk11=U2i*Dk11*Y2i + + Sk=list(E,Ak,Bk1,Bk2,Ck1,Ck2,Dk11,Dk12,Dk21,Dk22); +endfunction diff --git a/modules/cacsd/macros/h_inf_st.bin b/modules/cacsd/macros/h_inf_st.bin Binary files differnew file mode 100755 index 000000000..2da2ef10d --- /dev/null +++ b/modules/cacsd/macros/h_inf_st.bin diff --git a/modules/cacsd/macros/h_inf_st.sci b/modules/cacsd/macros/h_inf_st.sci new file mode 100755 index 000000000..4dcd74377 --- /dev/null +++ b/modules/cacsd/macros/h_inf_st.sci @@ -0,0 +1,47 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [Kopt,gamaopt]=h_inf_st(D,r) + //compute a matrix K such that largest singular value of + // Fl(D,r,K)=D11+D12 K inv(I-D22 K) D21 + //is minimal (Static H-infinity four blocks problem) + // + //[Kopt,gamaopt]=h_inf_st(D,r) + // + // D partionned as [D11 D12 + // D21 D22] + //where size(D22)=r=[r1 r2] + + + [l,k]=size(D); + l1=1:(l-r(1)); + l2=(l-r(1)+1):l; + k1=1:(k-r(2)) + k2=(k-r(2)+1):k; + D11=D(l1,k1); + D12=D(l1,k2); + D21=D(l2,k1); + D22=D(l2,k2); + [U,n]=rowcomp(D12); + //n=r(2) ? + if n<>r(2) then mprintf(gettext("%s: %s not full rank.\n"),"h_inf_st","D12"),end + U=U([n+1:l-r(1),1:n],:); //Bottom Compression + [V,m]=colcomp(D21); + //m=r(1) ? + if m<>r(1) then mprintf(gettext("%s: %s not full rank.\n"),"h_inf_st","D21"),end + // Update + D12=U*D12; + D11=U*D11*V; + D21=D21*V; + [Kinf,gamaopt]=parrot(D11,[n,m]) + D12c=D12(l-r(1)-n+1:l-r(1),:); + D21c=D21(:,k-r(2)-m+1:k-r(2)); + K#=D12c\Kinf/D21c; + Kopt=(eye()+K#*D22)\K# +endfunction diff --git a/modules/cacsd/macros/h_norm.bin b/modules/cacsd/macros/h_norm.bin Binary files differnew file mode 100755 index 000000000..f2aa67f5a --- /dev/null +++ b/modules/cacsd/macros/h_norm.bin diff --git a/modules/cacsd/macros/h_norm.sci b/modules/cacsd/macros/h_norm.sci new file mode 100755 index 000000000..7372c091b --- /dev/null +++ b/modules/cacsd/macros/h_norm.sci @@ -0,0 +1,158 @@ +// 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 [hinfnorm,frequency]=h_norm(Sl,rerr) + // produces the infinitynorm of a state-space system + // (the maximum over all frequencies of the maximum singular value). + // [hinfnorm [,frequency]]=h_norm(Sl,rerr) + // [hinfnorm [,frequency]]=h_norm(Sl) + // + // Sl : the state space system (see syslin) + // Rerr : max. relative error, default value 1e-8 + // + // hinfnorm : the infinitynorm of Sl + // frequency : frequency at which hinfnorm is achieved + // see also: linfn, linf + //! + // Version 3.2, 09-27-1990 + // Adapted from + // N.A. Bruinsma T.U.Delft/Philips Research Eindhoven, see also + // Systems & Control Letters, vol. 14 pp. 287-293. + if argn(2)<1 then + error(msprintf(gettext("%s: Wrong number of input argument(s): At least %d expected.\n"),.. + "h_norm",1)) + end + + sltyp=typeof(Sl) + if and(sltyp<>["rational","state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear dynamical system expected.\n"),.. + "h_norm",1)) + end + if sltyp=="rational" then Sl=tf2ss(Sl);end + if argn(2)==1 then + rerr=1e-8; + else + if type(rerr)<>1|size(rerr,"*")<>1 then + error(msprintf(gettext("%s: Wrong type for input argument: Scalar expected.\n"),"h_norm",2)) + end + if ~isreal(rerr)|rerr<=0 then + error(msprintf(gettext( "%s: Input argument #%d must be strictly positive.\n"),"h_norm",2)) + end + end; + + eps=1.d-8; + if Sl.dt=="d"|type(Sl.dt)==1 then + hinfnorm=dhnorm(Sl);frequency=[]; + return; + end + [a,b,c,d]=abcd(Sl); + eiga=spec(a); + if max(real(eiga)) >= -1e-12 then + warning(msprintf(_("%s: System is not stable.\n"),"h_norm")) + end + if argn(2)==1 then rerr=1e-8; end; + [no,ns] = size(c); [ns,ni] = size(b); + if min(ni,no) == 1 then isiso = 2; else isiso = 1; end; + [p,a] = hess(a); [u,d,v] = svd(d); b = p' * b * v; c = u' * c * p; + dtd = diag(d'*d); ddt = diag(d*d'); dtc = d' * c; + aj = sqrt(-1)*eye(ns); R1 = ones(ni,1); S1 = ones(no,1); + l = []; + + // compute starting value + q = ((imag(eiga) + 0.01 * ones(eiga)) ./ real(eiga)) ./ abs(eiga); + [q,i] = max(q); w = abs(eiga(i)); + svw = norm( c * ((w*aj*eye()-a)\b) + d ); + sv0 = norm( -c * (a\b) + d ); + svdd = norm(d); + [lb,i] = max([svdd sv0 svw]);l=lb; + w = [1.d30 0 w ]; M = w(i); + // to avoid numerical problems with Rinv and Sinv if lb == norm(d), lb must be + // enlarged to at least (1+1e-3)*lb; + if lb == svdd then lb=1.001*lb+eps;end; + for it = 1:15, + gam = (1 + 2 * rerr) * lb; gam2 = gam * gam; + Rinv = diag(R1./(dtd - gam2 * R1)); + Sinv = diag(S1./(ddt - gam2 * S1)); + + H11 = a-b*Rinv*dtc; + evH = spec([H11 -gam*b*Rinv*b'; gam*c'*Sinv*c -H11']); + idx = find(abs(real(evH)) < 1e-8 & imag(evH) >= 0); + imev= imag(evH(idx)); + [imev] = gsort(imev); + q = max(size(imev)); + if q <= 1 then + // q=1 can only happen in the first step if H-norm==maxsv(D) or H-norm==maxsv(0) + // due to inaccurate eigenvalue computation (so gam must be an upper bound). + ub = gam; + else + M = 0.5 * (imev(1:q-1) + imev(2:q)); M = M(1:isiso:q-1); + sv=[]; + for j = 1:max(size(M)), + sv = [sv max(svd(d + c*((M(j)*aj*eye() - a)\b)))]; + end; + lb = max(sv);l=[l;lb]; + end; + end; + if M == 1.d30 then + lb=svdd; + warning(msprintf(gettext("%s: norm cannot be computed. Relative accuracy smaller than 1e-3\nHinfnorm is probably exactly max sv(D)\nThe system might be all-pass"),"h_norm")) + end; + if exists("ub")==0 then ub=lb;end + hinfnorm = 0.5 * (ub+lb); frequency = M; + +endfunction + +function gama=dhnorm(Sl,tol,gamamax) + //discrete-time case (should be tested!!!) + //disp('warning: discrete-time h_norm is not fully tested!') + [lhs,rhs]=argn(0); + if rhs==1 then tol=0.00001;gamamax=10000000;end + if rhs==2 then gamamax=1000;end + gamamin=sqrt(%eps); + n=0; + while %T + gama=(gamamin+gamamax)/2;n=n+1; + if n>1000 then + warning(msprintf(gettext("%s: More than %d iterations.\n"),"dhnorm" ,1000)); + return; + end + if dhtest(Sl,gama) then + gamamax=gama; else gamamin=gama + end + if (gamamax-gamamin)<tol then return;end + end + +endfunction + +function ok=dhtest(Sl,gama) + //test if discrete hinfinity norm of Sl is < gama + [A,B,C,D]=abcd(Sl);B=B/sqrt(gama);C=C/sqrt(gama);D=D/gama; + R=eye()-D'*D; + [n,n]=size(A);Id=eye(n,n);Z=0*Id; + Ak=A+B*inv(R)*D'*C; + e=[Id,-B*inv(R)*B';Z,Ak']; + Aa=[Ak,Z;-C'*inv(eye()-D*D')*C,Id]; + [As,Es,w,k]=schur(Aa,e,"d"); + //Testing magnitude 1 eigenvalues. + [al,be]=spec(As,Es); + finite=find(abs(be)>0.00000001); + finite_eigen=al(finite)./be(finite); + bad=find( abs(abs(finite_eigen)-1) < 0.0000001); + if bad<>[] then ok=%f;return;end + //if k<>n then ok=%f;return;end + ws=w(:,1:n); + x12=ws(1:n,:); + phi12=ws(n+1:2*n,:); + if rcond(x12) > 1.d-6 then + X=phi12/x12; + z=eye()-B'*X*B + ok= min(real(spec(z))) > -%eps + else + ok=%t;end +endfunction diff --git a/modules/cacsd/macros/hallchart.bin b/modules/cacsd/macros/hallchart.bin Binary files differnew file mode 100755 index 000000000..ecfecccd6 --- /dev/null +++ b/modules/cacsd/macros/hallchart.bin diff --git a/modules/cacsd/macros/hallchart.sci b/modules/cacsd/macros/hallchart.sci new file mode 100755 index 000000000..9469da2bf --- /dev/null +++ b/modules/cacsd/macros/hallchart.sci @@ -0,0 +1,126 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 hallchart(modules,args,colors) + defaultmodules=[-20 -10 -6 -4 -2 2 4 6 10 20];//in dB + defaultargs=[-90 -60 -45 -30 -15 15 30 45 60 90]; //in degree + defaultbounds=[-3.5 -2;3 2]; + if exists("modules","local")==0 then + modules=defaultmodules + else + if type(modules)|~isreal(modules)<>1 then + error(msprintf("%s: Wrong type for imput argument ""%s"": real floating point array expected\n"),"hallchart","modules"); + end + modules=matrix(modules,1,-1) + end + if exists("args","local")==0 then + args=defaultargs + else + if type(args)<>1|~isreal(args) then + error(msprintf("%s: Wrong type for imput argument ""%s"": real floating point array expected\n"),"hallchart","args"); + end + args=matrix(args,1,-1) + end + + if exists("colors","local")==0 then + colors=[4 12]; + else + if type(colors)<>1|~isreal(colors) then + error(msprintf("%s: Wrong type for imput argument ""%s"": real floating point array expected\n"),"hallchart","colors"); + end + if size(colors,"*")==1 then + colors=colors*ones(1,2) + end + end + + fig=gcf(); + immediate_drawing=fig.immediate_drawing; + fig.immediate_drawing="off"; + + ax=gca(); + nc=size(ax.children,"*") + if nc==0 then + ax.data_bounds=defaultbounds; + ax.axes_visible="on"; + ax.x_label.text=_("Real axis"); + ax.y_label.text=_("Imaginary axis"); + ax.title.text=_("Hall chart") + ax.box="on"; + end + + //iso modules circles. Circles whose center are (-M^2/(M^2-1),0) and + //radius M/(M^2-1) with M=|H(jw)| and H=G/(1+G) + + M=exp(log(10)*modules/20) + radius=M./(M.*M-ones(M)) + xc=-M.*radius + yc=0 + radius=abs(radius) + //arcs replaced by polylines to be able to use datatips + // xarcs([xc-radius;yc+radius;2*radius;2*radius;0*M;360*64*ones(M)]) + // A=gce() + // E=unglue(A); + w=linspace(0,2*%pi,200) + c=cos(w);s=sin(w) + chart_handles=[] + for i=1:size(M,"*") + xpoly(xc(i)+radius(i)*c,yc+radius(i)*s) + ec=gce(); + ec.foreground=colors(1); + ec.line_style=7; + ec.clip_state="clipgrf"; + ec.display_function = "formatHallModuleTip"; + ec.display_function_data = modules(i); + if 2*int(i/2)==i then + xs=xc(i)+radius(i)*cos(%pi/6) + ys=yc+radius(i)*sin(%pi/6) + else + xs=xc(i)+radius(i)*cos(-%pi/6) + ys=yc+radius(i)*sin(-%pi/6) + + end + + xstring(xs,ys,string(modules(i))+_("dB")); + el=gce(); + + el.font_foreground=colors(1); + el.clip_state="clipgrf"; + chart_handles=[glue([el ec]) chart_handles]; + end + + //iso phase circles. Circles whose center are (-1/2, 1/(2*N)) and + //radius sqrt(1+N^2)/(2*N) with N=tan(arg(H(-jw))) + + N=tan(args*%pi/180); + radius=sqrt(1+N.^2)./(2*N); + xc=-1/2; + yc=1 ./(2*N); + + // xarcs([xc-radius;yc+radius;2*radius;2*radius;0*N;360*64*ones(N)]) + // E=unglue(gce()); + for i=1:size(N,"*") + xpoly(xc+radius(i)*c,yc(i)+radius(i)*s);ec=gce(); + ec.foreground=colors(2); + ec.line_style=7; + ec.clip_state="clipgrf"; + ec.display_function = "formatHallPhaseTip"; + ec.display_function_data = args(i); + xstring(xc,yc(i)+radius(i),msprintf("%g°",args(i))); + el=gce(); + el.font_foreground=colors(2); + el.clip_state="clipgrf"; + chart_handles=[glue([el ec]) chart_handles]; + end + chart_handles=glue(chart_handles) + //reorder axes children to make chart drawn before the previously + // drawn curves if any + for k=1:nc + swap_handles(ax.children(k),ax.children(k+1)) + end + fig.immediate_drawing=immediate_drawing; +endfunction diff --git a/modules/cacsd/macros/hankelsv.bin b/modules/cacsd/macros/hankelsv.bin Binary files differnew file mode 100755 index 000000000..bba2e9e2a --- /dev/null +++ b/modules/cacsd/macros/hankelsv.bin diff --git a/modules/cacsd/macros/hankelsv.sci b/modules/cacsd/macros/hankelsv.sci new file mode 100755 index 000000000..0f17ceb73 --- /dev/null +++ b/modules/cacsd/macros/hankelsv.sci @@ -0,0 +1,34 @@ +// 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 [nk,W]=hankelsv(sl,tol) + //! + if typeof(sl)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: State-space linear system expected.\n"),"hankelsv",1)), + end + if sl.dt==[] then + warning(msprintf(gettext("%s: Input argument %d is assumed continuous time.\n"),"hankelsv",1)); + sl.dt="c" + elseif sl.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Continuous-time linear system expected.\n"),"hankelsv",1)), + end + // + [lhs,rhs]=argn(0), + if rhs==1 then tol=1000*%eps,end, + lf=spec(sl(2)), + if min(abs(lf))<=tol then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Pure imaginary poles unexpected.\n"),"hankelsv",1)), + end + if max(real(lf)) > tol then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Stable system expected.\n"),"hankelsv",1)), + end, + [sla,sls,d]=dtsi(sl); + lc=ctr_gram(sls),lo=obs_gram(sls),W=lc*lo; + nk=gsort(real(spec(W))); +endfunction diff --git a/modules/cacsd/macros/imrep2ss.bin b/modules/cacsd/macros/imrep2ss.bin Binary files differnew file mode 100755 index 000000000..7dd757ad8 --- /dev/null +++ b/modules/cacsd/macros/imrep2ss.bin diff --git a/modules/cacsd/macros/imrep2ss.sci b/modules/cacsd/macros/imrep2ss.sci new file mode 100755 index 000000000..5bafd4e81 --- /dev/null +++ b/modules/cacsd/macros/imrep2ss.sci @@ -0,0 +1,27 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - Serge Steer +// +// 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 [sl]=imrep2ss(v,deg) + + [lhs,rhs]=argn(0) + // hankel + [no,nv]=size(v); + n=nv/2; + ns1=no-1;n2=n-1; + l=1; + h=0*ones(n,n); + for k=1:n,h(l:l+ns1,:)=v(:,k:k+n2),l=l+no,end; + //factorization + if rhs==1 then [u,h1,v1,deg]=svd(h);else [u,h1,v1]=svd(h);end + //extraction + obs=u(:,1:deg);con=h1*v1';con=con(1:deg,:); + //shift + obstild=obs(no+1:n*no,:);obstild(n*no,deg)=0; + sl=syslin("d",obs'*obstild,con(:,1),obs(1:no,:)) +endfunction diff --git a/modules/cacsd/macros/inistate.bin b/modules/cacsd/macros/inistate.bin Binary files differnew file mode 100755 index 000000000..b6c3375a4 --- /dev/null +++ b/modules/cacsd/macros/inistate.bin diff --git a/modules/cacsd/macros/inistate.sci b/modules/cacsd/macros/inistate.sci new file mode 100755 index 000000000..c877fc537 --- /dev/null +++ b/modules/cacsd/macros/inistate.sci @@ -0,0 +1,172 @@ +function [x0,V,rcnd]=inistate(A,B,C,D,y,u,tol,printw) + x0=[];V=[];rcnd=[]; + [nargout,nargin] = argn(0) + //INISTATE Estimates the initial state of a discrete-time system, given the + // (estimated) system matrices, and a set of input/output data. + // + // X0 = INISTATE(SYS,Y,U,TOL,PRINTW) estimates the initial state X0 of + // the discrete-time system SYS = (A,B,C,D), using the output data Y + // and the input data U. The model structure is : + // + // x(k+1) = Ax(k) + Bu(k), k >= 1, + // y(k) = Cx(k) + Du(k), + // + // The vectors y(k) and u(k) are transposes of the k-th rows of Y and U, + // respectively. + // Instead of the first input parameter SYS (an ss object), equivalent + // information may be specified using matrix parameters, for instance, + // X0 = INISTATE(A,B,C,Y,U); or X0 = INISTATE(A,C,Y); + // + // TOL is the tolerance used for estimating the rank of matrices. + // If TOL > 0, then the given value of TOL is used as a lower bound + // for the reciprocal condition number. + // Default: prod(size(matrix))*epsilon_machine where epsilon_machine + // is the relative machine precision. + // + // PRINTW is a select for printing the warning messages. + // PRINTW = 1: print warning messages; + // = 0: do not print warning messages. + // Default: PRINTW = 0. + // + // [x0,V,rcnd] = INISTATE(SYS,Y,U,TOL,PRINTW) returns, besides x0, + // the orthogonal matrix V which reduces the system state matrix A to + // a real Schur form, as well as an estimate of the reciprocal condition + // number of the coefficient matrix of the least squares problem solved. + // + // See also FINDBD, FINDX0BD + // + + // V. Sima 13-05-2000. + // + // For efficiency, most errors are checked in the mexfile findBD. Also, + // except for scalars, the input parameters are not copied, but renamed. + // + // Revisions: + // V. Sima, July 2000. + // + + ni = nargin; + if mtlb_isa(A,"lti") then + // Get the system matrices of the ss object, and the remaining parameters. + // General call x0 = inistate(A,B,C,D,y,u,tol,printw); + // Special call x0 = inistate(sys,y,u,tol,printw); + // + if A.dt=="c" then + error(msprintf(gettext("%s: Wrong values for input argument #%d: Discrete time system expected.\n"),"inistate",1)) + end + if ni<2 then + error(msprintf(gettext("%s: Wrong number of input arguments: At least %d expected.\n"),"inistate",2)); + end + [As,Bs,Cs,Ds] = abcd(A) + [ny,nu] = size(A); + [ty,p] = size(B); + if ni>2 then + [tu,m] = size(C); + if ~(((tu==ty|tu==0)&(m==nu))&(ty>1)) then + tol = C; + // Special call x0 = inistate(sys,y,tol,printw); + if ni>3 then + printw = D; + else + printw = 0; + end + // Below, B means y ! + [x0,Vl,rcndl] = findBD(1,3,As,Cs,B,tol,printw); + else + if ni>3 then + // Special call x0 = inistate(sys,y,u,tol,printw); + tol = D; + if ni>4 then + printw = y; + else + printw = 0; + end + else + tol = 0; + printw = 0; + end + // Below, B means y, and C means u ! + if norm(Ds,1)==0 then + [x0,Vl,rcndl] = findBD(1,2,1,As,Bs,Cs,B,C,tol,printw); + else + [x0,Vl,rcndl] = findBD(1,2,2,As,Bs,Cs,Ds,B,C,tol,printw); + end + end + else + // Special call x0 = inistate(sys,y); + // Below, B means y ! + [x0,Vl,rcndl] = findBD(1,3,As,Cs,B); + end + // + else + // The system matrices are directly specified. + // General call x0 = inistate(A,B,C,D,y,u,tol,printw); + // Special calls x0 = inistate(A,B,C,y,u,tol,printw); + // x0 = inistate(A,C,y,tol,printw); + // + if ni<3 then + error(msprintf(gettext("%s: Wrong number of input arguments: At least %d expected.\n"),"inistate",3)); + end + [m2,n2] = size(B); + [m3,n3] = size(C); + if ni>=4 then + [m4,n4] = size(D); + if ni>=5 then + [m5,n5] = size(y); + if ni>=6 then + [m6,n6] = size(u); + if ni>=7 then + if (ni==7)&(m6*n6>1) then + // Special call x0 = inistate(A,B,C,D,y,u,tol); + [x0,Vl,rcndl] = findBD(1,2,1,A,B,C,D,y,u,tol); + elseif ni==7 then + // Special call x0 = inistate(A,B,C,y,u,tol,printw); + // Below, D means y and y means u ! + printw = tol; + tol = u; + [x0,Vl,rcndl] = findBD(1,2,1,A,B,C,D,y,tol,printw); + else + [x0,Vl,rcndl] = findBD(1,2,2,A,B,C,D,y,u,tol,printw); + end + else + if m6*n6>1 then + [x0,Vl,rcndl] = findBD(1,2,2,A,B,C,D,y,u); + else + // Special call x0 = inistate(A,B,C,y,u,tol); + // Below, y means U and D means y ! + tol = u; + [x0,Vl,rcndl] = findBD(1,2,1,A,B,C,D,y,tol); + end + end + else + // Special calls x0 = inistate(A,B,C,y,u); + // x0 = inistate(A,C,y,tol,printw); + if m5*n5>1 then + // Below, y means u and D means y ! + [x0,Vl,rcndl] = findBD(1,2,1,A,B,C,D,y); + else + // Below, C means y and B means C ! + tol = D; + printw = y; + [x0,Vl,rcndl] = findBD(1,3,A,B,C,tol,printw); + end + end + else + // Below, D means tol, C means y, and B means C ! + [x0,Vl,rcndl] = findBD(1,3,A,B,C,D); + end + else + // Below, C means y, and B means C ! + [x0,Vl,rcndl] = findBD(1,3,A,B,C); + end + end + // + if nargout>2 then + V = Vl; + rcnd = rcndl; + elseif nargout>1 then + V = Vl; + end + // + // end inistate +endfunction diff --git a/modules/cacsd/macros/invrs.bin b/modules/cacsd/macros/invrs.bin Binary files differnew file mode 100755 index 000000000..27d653329 --- /dev/null +++ b/modules/cacsd/macros/invrs.bin diff --git a/modules/cacsd/macros/invrs.sci b/modules/cacsd/macros/invrs.sci new file mode 100755 index 000000000..3fecdbe45 --- /dev/null +++ b/modules/cacsd/macros/invrs.sci @@ -0,0 +1,38 @@ +// 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 Sli=invrs(Sl,alfa); + // Sli=invrs(Sl,alfa) computes Sli, the PSSD + // inverse of PSSD Sl. + //! + if typeof(Sl)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"invrs",1)) + end + + D=Sl.D; + if type(D)==2 then + s=poly(0,varn(D)); + Sl.D=horner(Sl.D,s+alfa); + end + Sl.A=Sl.A-alfa*eye(Sl.A); //Slnew(s)=Slold(s+alfa) + + [Sreg,Wss]=rowregul(Sl,0,0); + if rcond(Sreg.D) >1.d-6 then + Sli=invsyslin(Sreg)*Wss; + else + error(msprintf(gettext("%s: Square but singular system.\n"),"invrs")); + end + [Q,M]=pbig(Sli.A,0.001,"d"); + Sli=projsl(Sli,Q,M);//Remove poles at zero. + + if Sli.A~=[] then Sli.A=Sli.A+alfa*eye();end + if type(Sli.D)==2 then + Sli.D=horner(Sli.D,s-alfa); + end +endfunction diff --git a/modules/cacsd/macros/invsyslin.bin b/modules/cacsd/macros/invsyslin.bin Binary files differnew file mode 100755 index 000000000..b9f6461a4 --- /dev/null +++ b/modules/cacsd/macros/invsyslin.bin diff --git a/modules/cacsd/macros/invsyslin.sci b/modules/cacsd/macros/invsyslin.sci new file mode 100755 index 000000000..13db9e1bb --- /dev/null +++ b/modules/cacsd/macros/invsyslin.sci @@ -0,0 +1,23 @@ +// 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 it=invsyslin(t) + + if typeof(t)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"invsyslin",1)) + end + + [p,m]=size(t.D); + if p <> m then + warning(msprintf(gettext("%s: Wrong size for input argument #%d: Square system expected.\n"),"invsyslin",1)), + end + // + d=pinv(t.D); + it=syslin(t.dt,t.A-t.B*d*t.C,t.B*d,-d*t.C,d,t.X0); +endfunction diff --git a/modules/cacsd/macros/kpure.bin b/modules/cacsd/macros/kpure.bin Binary files differnew file mode 100755 index 000000000..e9918658f --- /dev/null +++ b/modules/cacsd/macros/kpure.bin diff --git a/modules/cacsd/macros/kpure.sci b/modules/cacsd/macros/kpure.sci new file mode 100755 index 000000000..428b6493d --- /dev/null +++ b/modules/cacsd/macros/kpure.sci @@ -0,0 +1,49 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - Serge Steer +// +// 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 [K,R]=kpure(sl,eps) + //if sl is a transfert function N(S)/D(s) kpure looks for K producing + //pure imaginary roots for + // P(s)=D(s)+K*N(s) + //There is a pair of pure imaginary poles if and only if + // P(%i*q)=0 (1) + // and + // P(-%i*q)=0 (2) + // because N and D are polynomials with real coefficients. + + //Author: Serge Steer, INRIA + y=[];R=[]; + msg=_("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n") + if argn(2)==1 then eps=1e-6,end + if size(eps,"*")==2 then eps=eps(2),end //compatibility + select typeof(sl) + case "rational" then + if size(sl.num,"*") <> 1 then + error(msprintf(msg,"kpure",1)) + end + case "state-space" then + if size(sl.D,"*") <> 1 then + error(msprintf(msg,"kpure",1)) + end + sl=ss2tf(sl) + else + error(msprintf(msg,"kpure",1)) + end + + //(1) give K(s)=-D(s)/N(s) + s=poly(0,varn(sl.den)) + K=-sl.den/sl.num; + // replace K by the previous value in (2) and find the roots + s=roots(numer(horner(sl.den,-s)+K*horner(sl.num,-s)),"e"); + //retain pure imaginary roots + s=imag(s(abs(real(s))<eps)); + R=(s(s>0).'*%i); + //find the K(s) values K(s)=-D(s)/N(s) + K=-real(freq(sl.den,sl.num,R)) +endfunction diff --git a/modules/cacsd/macros/krac2.bin b/modules/cacsd/macros/krac2.bin Binary files differnew file mode 100755 index 000000000..40827bf50 --- /dev/null +++ b/modules/cacsd/macros/krac2.bin diff --git a/modules/cacsd/macros/krac2.sci b/modules/cacsd/macros/krac2.sci new file mode 100755 index 000000000..2053329c9 --- /dev/null +++ b/modules/cacsd/macros/krac2.sci @@ -0,0 +1,41 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - Serge Steer +// +// 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 [kp,s]=krac2(sys) + //The denominator of the closed loop system is den(s)+K*num(s). So the + // the closed loops poles verify K(s)=-den(s)/num(s) + //The real axis breakaway points occurs at the extrema of the K(s) + // so at the point where K'=dK/ds = 0 + // K'=-(den'*num-den*num')/num^2 + // K'= 0 --> den'*num-den*num'=0 + // http://www.scribd.com/doc/21374148/An-Introduction-to-Control-Systems + select typeof(sys) + case "rational" then + case "state-space" then + sys=ss2tf(sys); + else + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"krac2",1)) + end + if size(sys,"*")<>1 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Single input, single output system expected.\n"),"krac2",1)) + end + num=sys.num + den=sys.den + s=roots(derivat(num)*den-derivat(den)*num,"e") + //collect the real roots only + i=find(abs(imag(s))<=10*%eps) + if i==[] then kp=[],s=[];return,end + s=s(i)'; + s=s(horner(num,s)<>0); + + kp=-real(freq(den,num,real(s))); + i=find(kp>=0); + kp=kp(i) + s=s(i) +endfunction diff --git a/modules/cacsd/macros/lcf.bin b/modules/cacsd/macros/lcf.bin Binary files differnew file mode 100755 index 000000000..866c416b1 --- /dev/null +++ b/modules/cacsd/macros/lcf.bin diff --git a/modules/cacsd/macros/lcf.sci b/modules/cacsd/macros/lcf.sci new file mode 100755 index 000000000..ed38155df --- /dev/null +++ b/modules/cacsd/macros/lcf.sci @@ -0,0 +1,39 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [N,M]=lcf(Sl) + //Compute Normalized coprime factorization of a linear dynamic system + //%Syntax and parameters description + // [N,M]=lcf(Sl) + // + // SL : linear dynamic system given in state space or transfer function. + // see syslin + // N,M : is realization of Sl: Sl = M^-1 N + //! + + if and(typeof(Sl)<>["rational","state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"lcf",1)) + end + if Sl.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"lcf",1)) + end + flag=0; + if typeof(Sl)=="rational" then Sl=tf2ss(Sl),flag=1;end + + [A,B,C,D]=Sl(2:5);[nw,nb]=size(B);[nc,nw]=size(C); + R=eye()+D*D'; + [Z,H]=gfare(Sl); + Ar=A+H*C; + Bn=B+H*D;Bm=H; + Rm12=inv(sqrtm(R)); + Cr=Rm12*C;Dn=Rm12*D;Dm=Rm12; + N=syslin("c",Ar,Bn,Cr,Dn); + M=syslin("c",Ar,Bm,Cr,Dm); + if flag==1 then N=ss2tf(N);M=ss2tf(M);end +endfunction diff --git a/modules/cacsd/macros/leqe.bin b/modules/cacsd/macros/leqe.bin Binary files differnew file mode 100755 index 000000000..d112939cb --- /dev/null +++ b/modules/cacsd/macros/leqe.bin diff --git a/modules/cacsd/macros/leqe.sci b/modules/cacsd/macros/leqe.sci new file mode 100755 index 000000000..bc405f23d --- /dev/null +++ b/modules/cacsd/macros/leqe.sci @@ -0,0 +1,18 @@ +// 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 [K,Y,err]=leqe(P21,Qx) + if typeof(P21)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"leqe",1)) + end + + [A,B1,C2,D21,xo,dom]=P21(2:7) + [KT,Y,err]=leqr(syslin(dom,A',C2',B1',D21'),Qx); + K=KT'; +endfunction diff --git a/modules/cacsd/macros/leqr.bin b/modules/cacsd/macros/leqr.bin Binary files differnew file mode 100755 index 000000000..77138f7ca --- /dev/null +++ b/modules/cacsd/macros/leqr.bin diff --git a/modules/cacsd/macros/leqr.sci b/modules/cacsd/macros/leqr.sci new file mode 100755 index 000000000..e0fe2ce90 --- /dev/null +++ b/modules/cacsd/macros/leqr.sci @@ -0,0 +1,105 @@ +// 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 [k,x,err]=leqr(p12,vx) + //h-infinity lqr gain for full-state lq problem + //(discrete or continuous) + // + // discrete continuous + // |i -vx 0| | a 0 b| |i 0 0| | a vx b | + // z|0 a' 0| - |-c'c i -s| s|0 i 0| - |-c'c -a' -s | + // |0 b' 0| | s' 0 d'd| |0 0 0| | s' -b' d'd| + // + + [lhs,rhs]=argn(0); + + if typeof(p12)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"leqr",1)) + end + [a,b2,c1,d12]=p12(2:5); + [n,nu]=size(b2); + [ny,n]=size(c1); + dom=p12(7); + if dom==[] then + dom="c"; + warning(msprintf(gettext("%s: Input argument %d is assumed continuous time.\n"),"leqr",1)); + end + select dom + // continuous + case "c" then + z=0*a;i=eye(a); + q=c1'*c1;r=d12'*d12;s=c1'*d12; + bige=[i,z,zeros(b2); + z,i,zeros(b2); + zeros(nu,2*n+nu)]; + biga=[a,vx,b2; + -q,-a',-s; + s',b2',r]; + + [bige,biga,dummy,z]=balanc(bige,biga); + [w,k]=schur(biga,bige,"c"); + if k<>n then + warning(msprintf(gettext("%s: Stable subspace is too small.\n"),"leqr")); + k=[];w=[];err=[]; + return; + end + + ws=z*w(:,1:n); + x12=ws(1:n,:); + if rcond(x12) < 1.d-6 then + warning(msprintf(gettext("%s: Bad conditionning.\n"),"leqr")); + end + k=ws(2*n+1:2*n+nu,:)/x12; + x=ws(n+1:2*n,:)/x12; + if lhs~=3 then return;end + ri=pinv(r); + err=norm((a-b2*ri*s')'*x+x*(a-b2*ri*s')-x*(b2*ri*b2'-vx)*x+q-s*ri*s',1) + //k=-ri*(b2'*x+s') + // discrete time + case "d" then + i=eye(a);z=0*i; + q=c1'*c1;r=d12'*d12;s=c1'*d12; + bige=[i,-vx,zeros(b2); + z,a',zeros(b2); + zeros(b2'),-b2',zeros(b2'*b2)]; + biga=[a,z,b2; + -q,i, -s; + s', 0*b2', r]; + [bige,biga,dummy,z]=balanc(bige,biga); + [w,k]=schur(biga,bige,"d"); + if k<>n then + warning(msprintf(gettext("%s: Stable subspace is too small.\n"),"leqr")); + k=[];w=[];err=[]; + return; + end + ws=z*w(:,1:n); + x12=ws(1:n,:); + if rcond(x12) <1.d-6 then + warning(msprintf(gettext("%s: Bad conditionning.\n"),"leqr")); + k=[];w=[]; + return; + end + + k=ws(2*n+1:2*n+nu,:)/x12; + x=ws(n+1:2*n,:)/x12; + if norm(x-x',1)>0.0001 then + warning(msprintf(gettext("%s: %s non symmetric.\n"),"leqr","x")); + k=[];w=[]; + return; + end + + //a'*x*a-(a'*x*b2+c1'*d12)*pinv(b2'*x*b2+d12'*d12)*(b2'*x*a+d12'*c1)+c1'*c1 + if lhs~=3 then return;end + ri=pinv(r); + abar=a-b2*ri*s'; + qbar=q-s*ri*s'; + err=norm(x-(abar'*inv((inv(x)+b2*ri*b2'-vx))*abar+qbar),1); + //k=-ri*(b2'*inv(inv(x)+b2*ri*b2'-vx)*abar+s') + end +endfunction diff --git a/modules/cacsd/macros/lft.bin b/modules/cacsd/macros/lft.bin Binary files differnew file mode 100755 index 000000000..2b8286918 --- /dev/null +++ b/modules/cacsd/macros/lft.bin diff --git a/modules/cacsd/macros/lft.sci b/modules/cacsd/macros/lft.sci new file mode 100755 index 000000000..4754bb7d2 --- /dev/null +++ b/modules/cacsd/macros/lft.sci @@ -0,0 +1,318 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [p1,r1]=lft(p,r,p#,r#) + //[p1,r1]=lft(p,r,p#,r#) + //linear fractional transform between two standard plants + //p and p# in state space form or in transfer form. + //r= size(p22) r#=size(p22#); + // lft(p,r, k) is the linear fractional transform between p and + // a controller k (k may be a gain or a controller in + // state space form or in transfer form); + // lft(p,k) is lft(p,r,k) with r=size of k transpose; + //! + [lhs,rhs]=argn(0); + + if type(p)==1 then + p=syslin([],[],[],[],p); + else + if and(typeof(p)<>["rational","state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"lft",1)) + end + end + dom=p.dt + + p#pos=3 + if rhs==2 then + rhs=3;p#=r; + r=size(p#'); + p#pos=2 + end //rhs=2 + + if and(typeof(p#)<>["constant","rational","state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"lft",p#pos)) + end + + pssdflag=%f; + if typeof(p)=="state-space" then + if typeof(p.D)=="polynomial" then + pssdflag=%t; + end + end + if typeof(p#)=="state-space" then + if typeof(p#.D)=="polynomial" then + pssdflag=%t; + end + end + if pssdflag then + if rhs==3 then + [p1,r1]=lftpssd(p,r,p#);return; + end + if rhs==4 then + [p1,r1]=lftpssd(p,r,p#,r#);return; + end + end + if rhs==3 then + if type(p)==1 then + // lft( gain, linear system in ss form) + [nl,nc]=size(p); + l1=1:nc-r(1); + l2=nc-r(1)+1:nc; + k1=1:nl-r(2); + k2=nl-r(2)+1:nl; + d11=p(l1,k1);d12=p(l1,k2);d21=p(l2,k1);d22=p(l2,k2); + if type(p#)==1 then + //p# is a gain + dk=p#, + id=inv(eye(d22*dk)-d22*dk), + dd=d11+d12*dk*id*d21, + p1=dd; + else + // p# is not a gain + p#1=p#(1) + if p#1(1)=="lss" then + [ak,bk,ck,dk]=p#(2:5); + id=inv(eye(d22*dk)-d22*dk), + aa= ak+bk*id*d22*ck, + bb=bk*id*d21, + cc=d12*(ck+dk*id*d22*ck), + dd=d11+d12*dk*id*d21; + p1=syslin(dom,aa,bb,cc,dd) + end + if p#1(1)=="r" then + p1=d11+d12*p#*invr(eye()-d22*p#)*d21; + end + end + end //type(p)=1 + pof1=p(1); + if pof1(1)=="lss" then + // lft(standard in ss form,linear system in ss form) + [a,b1,b2,c1,c2,d11,d12,d21,d22]=smga(p,r); + if type(p#)==1 then + //p# is a gain + dk=p#, + id=inv(eye(d22*dk)-d22*dk), + aa=a+b2*dk*id*c2; + bb=b1+b2*dk*id*d21, + cc=c1+d12*dk*id*c2, + dd=d11+d12*dk*id*d21, + p1=syslin(dom,aa,bb,cc,dd) + else + // p# is not a gain + [ak,bk,ck,dk]=p#(2:5); + id=inv(eye(d22*dk)-d22*dk); + aa=[a+b2*dk*id*c2, b2*(ck+dk*id*d22*ck); + bk*id*c2, ak+bk*id*d22*ck], + bb=[b1+b2*dk*id*d21;bk*id*d21], + cc=[c1+d12*dk*id*c2, d12*(ck+dk*id*d22*ck)], + dd=d11+d12*dk*id*d21; + p1=syslin(dom,aa,bb,cc,dd) + end + end + if pof1(1)=="r" then + //lft(standard plant in tf form,linear system in tf form) + [p11,p12,p21,p22]=smga(p,r); + p1=p11+p12*p#*invr(eye()-p22*p#)*p21 + end //p(1)=='lss' + end //rhs=3 + if rhs==4 then + + if type(p)==1 then + //lft(gain,standard plant ) + [nl,nc]=size(p); + l1=1:nc-r(1); + l2=nc-r(1)+1:nc; + k1=1:nl-r(2); + k2=nl-r(2)+1:nl; + d11=p(l1,k1);d12=p(l1,k2);d21=p(l2,k1);d22=p(l2,k2); + if type(p#)==1 then + //p# is a gain + [nl,nc]=size(p#); + l1=1:nc-r#(1); + l2=nc-r#(1)+1:nc; + k1=1:nl-r#(2); + k2=nl-r#(2)+1:nl; + d#11=p#(l1,k1);d#12=p#(l1,k2);d#21=p#(l2,k1);d#22=p#(l2,k2); + + g=inv(eye()-d22*d#11); + g#=inv(eye()-d#11*d22); + + dd11=d11+d12*g#*d#11*d21; + dd12=d12*g#*d#12; + dd21=d#21*g*d21; + dd22=d#22+d#21*g*d22*d#12; + + p1=[dd11,dd12;dd21,dd22]; + r1=size(dd22); + end + p#1=p#(1); + if p#1(1)=="lss" + //p# in state form + [a#,b#1,b#2,c#1,c#2,d#11,d#12,d#21,d#22]=smga(p#,r#); + g=inv(eye()-d22*d#11); + g#=inv(eye()-d#11*d22); + + aa=a#+b#1*g*d22*c#1; + + bb1= b#1*g*d21; + bb2= b#2+b#1*g*d22*d#12; + + cc1= d12*g#*c#1; + cc2= c#2+d#21*g*d22*c#1; + + dd11=d11+d12*g#*d#11*d21; + dd12=d12*g#*d#12; + dd21=d#21*g*d21; + dd22=d#22+d#21*g*d22*d#12; + + p1=syslin(dom,aa,[bb1,bb2],[cc1;cc2],[dd11,dd12;dd21,dd22]); + r1=size(dd22); + end + if p#1(1)=="r" then + [j11,j12,j21,j22]=smga(p#,r#); + + g=invr(eye()-d22*j11); + g#=invr(eye()-j11*d22); + + ptfg11=d11+d12*j11*g*d21; + ptfg12=d12*g#*j12; + //ptfg21=j21*g*p21; + ptfg21=j21*(eye()+d22*g#*j11)*d21; + ptfg22=j22+j21*d22*g#*j12; + + p1=[ptfg11,ptfg12;ptfg21,ptfg22]; + r1=size(ptfg22) + + end + end //type(p)=1 + pof1=p(1); + if pof1(1)=="lss" then + //lft(standard plant in ss form,standard plant in ss form) + [a ,b1,b2,c1,c2,d11,d12,d21,d22]=smga(p,r); + + if type(p#)==1 then + //p# is a gain + [nl,nc]=size(p#); + l1=1:nc-r#(1); + l2=nc-r#(1)+1:nc; + k1=1:nl-r#(2); + k2=nl-r#(2)+1:nl; + d#11=p#(l1,k1);d#12=p#(l1,k2);d#21=p#(l2,k1);d#22=p#(l2,k2); + + g=inv(eye()-d22*d#11); + g#=inv(eye()-d#11*d22); + + aa=a+b2*g#*d#11*c2; + + bb1=b1+b2*g#*d#11*d21; + bb2=b2*g#*d#12; + + cc1=c1+d12*g#*d#11*c2; + cc2=d#21*g*c2; + + dd11=d11+d12*g#*d#11*d21; + dd12=d12*g#*d#12; + dd21=d#21*g*d21; + dd22=d#22+d#21*g*d22*d#12; + + p1=syslin(dom,aa,[bb1,bb2],[cc1;cc2],[dd11,dd12;dd21,dd22]); + r1=size(dd22); + + else + //p# in state form + [a#,b#1,b#2,c#1,c#2,d#11,d#12,d#21,d#22]=smga(p#,r#); + g=inv(eye()-d22*d#11); + g#=inv(eye()-d#11*d22); + + aa=[a+b2*g#*d#11*c2 b2*g#*c#1; + b#1*g*c2 a#+b#1*g*d22*c#1]; + + bb1=[b1+b2*g#*d#11*d21; + b#1*g*d21]; + + bb2=[b2*g#*d#12; + b#2+b#1*g*d22*d#12]; + + cc1=[c1+d12*g#*d#11*c2 d12*g#*c#1]; + + cc2=[d#21*g*c2 c#2+d#21*g*d22*c#1]; + dd11=d11+d12*g#*d#11*d21; + + dd12=d12*g#*d#12; + + dd21=d#21*g*d21; + + dd22=d#22+d#21*g*d22*d#12; + + p1=syslin(dom,aa,[bb1,bb2],[cc1;cc2],[dd11,dd12;dd21,dd22]); + r1=size(dd22);return; + end // type(p#)=1 + end //p(1)=='lss' + pof1=p(1); + if pof1(1)=="r" then + //lft(standard plant in tf form,standard plant in tf form) + [p11,p12,p21,p22]=smga(p,r); + [j11,j12,j21,j22]=smga(p#,r#); + + g=invr(eye()-p22*j11); + g#=invr(eye()-j11*p22); + + ptfg11=p11+p12*j11*g*p21; + ptfg12=p12*g#*j12; + //ptfg21=j21*g*p21; + ptfg21=j21*(eye()+p22*g#*j11)*p21; + ptfg22=j22+j21*p22*g#*j12; + + p1=[ptfg11,ptfg12;ptfg21,ptfg22]; + r1=size(ptfg22) + end //p(1)='r' + end //rhs=4 + +endfunction +function [lf,r1]=lftpssd(p,r,k,r2) + //lft for pssd (inria report #1827, dec. 1992) + [lhs,rhs]=argn(0); + if rhs==2 then + rhs=3;k=r;r=size(k'); + end + if rhs==3 then + [pp,qq]=size(p); + l1=pp-r(1);k1=qq-r(2); + l2=r(1);k2=r(2); + [l3,k4]=size(k); + l4=k1;k3=l1; + psi=[p,[-eye(l1,k3),zeros(l1,k4); + zeros(l2,k3),-eye(l2,k4)]; + zeros(l3,k1),-eye(l3,k2),zeros(l3,k3),k; + eye(l4,k1),zeros(l4,k2+k3+k4)]; + w=clean(ss2tf(psi)); + lf=[zeros(k3,k1+k2),eye(k3,k3),zeros(k3,k4)]*inv(psi)*... + [zeros(l1+l2+l3,l4);eye(l4,l4)]; + r1=[l1,k1]; + return; + end + if rhs==4 then + [pp,qq]=size(p); + l1=pp-r(1);k1=qq-r(2); + l2=r(1);k2=r(2); + [pk,qk]=size(k); + l3=pk-r2(1);k5=qk-r2(2); + l4=r2(1);k6=r2(2); + l5=k1;k3=l4;k4=l1;l6=k6; + psi=... + [p,[zeros(l1,k3),-eye(l1,k4);zeros(l2,k3+k4)],[zeros(l1,k5+k6);-eye(l2,k5),zeros(l2,k6)]; + [zeros(l3,k1),-eye(l3,k2);zeros(l4,k1+k2)],[zeros(l3,k3+k4);-eye(l4,k3),zeros(l4,k4)],k; + [eye(l5,k1),zeros(l5,k2+k3+k4+k5+k6);zeros(l6,k1+k2+k3+k4+k5),eye(l6,k6)]]; + lf=... + [zeros(k4,k1+k2+k3),eye(k4,k4),zeros(k4,k5+k6); + zeros(k3,k1+k2),eye(k3,k3),zeros(k3,k4+k5+k6)]*inv(psi)*... + [zeros(l1+l2+l3+l4,l5+l6);eye(l5+l6,l5+l6)]; + r1=[k3,l6]; + end +endfunction diff --git a/modules/cacsd/macros/lib b/modules/cacsd/macros/lib Binary files differnew file mode 100755 index 000000000..daee141d7 --- /dev/null +++ b/modules/cacsd/macros/lib diff --git a/modules/cacsd/macros/lin.bin b/modules/cacsd/macros/lin.bin Binary files differnew file mode 100755 index 000000000..99f418328 --- /dev/null +++ b/modules/cacsd/macros/lin.bin diff --git a/modules/cacsd/macros/lin.sci b/modules/cacsd/macros/lin.sci new file mode 100755 index 000000000..8231230d9 --- /dev/null +++ b/modules/cacsd/macros/lin.sci @@ -0,0 +1,43 @@ +// 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 [a,b,c,d]=lin(sim,x0,u0) + //Syntaxes : sl=lin(sim,x0,u0) or + // [a,b,c,d]=lin(sim,x0,u0) + // + //linearization of the non-linear differential system [y,xdot]=sim(x,u) + //around x0 , u0. (sim is a scilab macro which computes y and xdot). + //output: + //- linear system sl (syslin list) + //- (a,b,c,d) + // + // Example : Let ftz be the function passed to ode e.g. + // [zd]=ftz(t,z,u), and let us assume y=x. + // [z]=ode(x0,t0,tf,list(ftz,u) compute x(tf) + // Let simula be the following function: + // function [y,xd]=simula(x,u) + // xd=ftz(tf,x,u); y=x; + // + // The tangent linear system sl is obtained by: + // [a,b,c,d]=lin(simula,z,u) + // sl = syslin('c',a,b,c,d,x0) + //! + + [lhs,rhs]=argn(0) + [n,w]=size(x0);[m,w]=size(u0);mpn=m+n + nrm=norm([x0;u0]);if nrm<1 then nrm=1,end; + [zz,nu]=colcomp(rand(mpn,mpn)); + d=10*%eps*nrm*zz(:,1:nu); [y,xd]=sim(x0,u0); y0=[xd;y]; + ab=[];for v=d,[y,xd]=sim(x0+v(1:n),u0+v(n+1:mpn)), + ab=[ab,([xd;y]-y0)],end + [p,w]=size(y); + ab=ab/d;a=ab(1:n,1:n);b=ab(1:n,n+1:mpn) + c=ab(n+1:n+p,1:n);d=ab(n+1:n+p,n+1:mpn) + if lhs==1 then a=syslin("c",a,b,c,d,x0),end +endfunction diff --git a/modules/cacsd/macros/linf.bin b/modules/cacsd/macros/linf.bin Binary files differnew file mode 100755 index 000000000..c24f56a47 --- /dev/null +++ b/modules/cacsd/macros/linf.bin diff --git a/modules/cacsd/macros/linf.sci b/modules/cacsd/macros/linf.sci new file mode 100755 index 000000000..7cb6ef315 --- /dev/null +++ b/modules/cacsd/macros/linf.sci @@ -0,0 +1,68 @@ +// 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 [n]=linf(g,eps,tol) + //linf(g,[eps],[tol]) L_infinity norm + // n=sup [sigmax(g(jw)] (sigmax largest singular value). + // w + //-- g is a syslin system. + //-- eps is error tolerance on n. + //-- tol threshold for imaginary axis poles. + // See also: h_norm + //! + if type(g)==1,if norm(g)==0,n=0,return,end,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"),"linf",1)) + end + if g.dt<>"c"&g.dt<>[] then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Continuous time system expected.\n"),"linf",1)) + end + g.dt="c" + if typeof(g)=="rational" then g=tf2ss(g),end + + [lhs,rhs]=argn(0), + select rhs, + case 1 then eps=1e-7,tol=1000*%eps, + case 2 then tol=1000*%eps, + end, + [a,b,c,d]=g(2:5),[t,t]=size(a), + p=ctr_gram(g),q=obs_gram(g); + //Algorithm: + //---------- + //1. min , max. + //---------------------------------- + [slp,slm]=dtsi(g), + if slp==0 then pp=0,qq=0,tp=1, + pm=p,qm=q,tm=t, + else + if slm==0 then pm=0,qm=0,tm=1, + pp=p,qq=q,tp=t, + else + [tp,tp]=size(slp(2)),[tm,tm]=size(slm(2)), + pp=ctr_gram(slp),qq=obs_gram(slp), + pm=ctr_gram(slm),qm=obs_gram(slm), + end, + end, + hsvp=sqrt(spec(pp*qq)),hsvp=gsort(real(hsvp)), + hsvm=sqrt(spec(pm*qm)),hsvm=gsort(real(hsvm)), + gl=max([norm(d),hsvp(tp),hsvm(tm)]), + gu=norm(d)+2*(sum(hsvp)+sum(hsvm)), + //2. binary search + //---------------------- + while gu-gl>2*eps*gl, + x=(gl+gu)/2, + r=d'*d-(x*x)*eye(),s=d*d'-(x*x)*eye(), + mx=[a-b/r*d'*c, -x*b/r*b'; .. + x*c'/s*c, -a'+c'*d/r*b'], + mp=abs(real(spec(mx))),mp=min(mp), + if mp>tol then gu=x, else gl=x, end, + end; + n=(gu+gl)/2 +endfunction diff --git a/modules/cacsd/macros/linfn.bin b/modules/cacsd/macros/linfn.bin Binary files differnew file mode 100755 index 000000000..5ac9cb9d0 --- /dev/null +++ b/modules/cacsd/macros/linfn.bin diff --git a/modules/cacsd/macros/linfn.sci b/modules/cacsd/macros/linfn.sci new file mode 100755 index 000000000..39ebafa08 --- /dev/null +++ b/modules/cacsd/macros/linfn.sci @@ -0,0 +1,486 @@ +// 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 [x,frequ]=linfn(G,PREC,RELTOL,options); + //[x,frequ]=linfn(G,PREC,RELTOL,options); + // Computes the Linf (or Hinf) norm of a transfer function + // -1 + // G(s) = D + C (sI - A) B + // + // This norm is well-defined as soon as the realization + // (A,B,C) has no imaginary eval which is both controllable and observable. + // + // The algorithm follows the paper by G. Robel (AC-34 pp. 882-884, 1989). + // The case D=0 is not treated separately due to superior accuracy of + // the general method when (A,B,C) is nearly nonminimal. + // + // In the general case (A neither stable nor antistable), no upper bound is + // prespecified. If by contrast A is stable or antistable, lower + // and upper bounds are computed using the associated Lyapunov + // solutions (see Glover). + + + // On input: + // --------- + // * G is a syslin list + // * PREC is the desired relative accuracy on the norm + // * RELTOL: relative threshold to decide when an eigenvalue can be + // considered on the imaginary axis. + // * available options are + // - 'trace': traces each bisection step, i.e., displays the lower + // and upper bounds and the current test point. + // - 'cond': estimates a confidence index on the computed value + // and issues a warning if computations are + // ill-conditioned + // + // On output: + // --------- + // * x is the computed norm. + // * freq: list of the frequencies for which ||G|| is attained, i.e., + // such that ||G (j om)|| = ||G||. If -1 is in the list, the norm + // is attained at infinity. If -2 is in the list, G is all-pass in + // some direction so that ||G (j omega)|| = ||G|| for all + // frequencies omega. + //! + // + // Called macros: + // ------------- + // heval_test, cond_test, list_set + // + // History: + // ------- + // author: P. Gahinet, INRIA + // last modification: Oct 3nd, 1991 + //**************************************************************************** + + + //constants + //********* + INIT_LOW=1.0e-4; INIT_UPP=1.0e5; INFTY=10e10; + frequ=[]; + + + //user interface. The default values are: + // PREC=1.0e-3; RELTOL=1.0e-10; options='nul'; + //************************************************ + [lhs,rhs]=argn(0); + select rhs, + case 0 then + error(msprintf(gettext("%s: Wrong number of input arguments: At least %d expected.\n"),"linfn",1)) + case 1 then + PREC=1.0e-3; RELTOL=1.0e-10; options="nul"; + case 2 then + RELTOL=1.0e-10; + if type(PREC)==10 then + iopt=2 + options=PREC; PREC=1.0e-3; + else + options="nul"; + end, + case 3 then + if type(RELTOL)==10 then + iopt=3 + options=RELTOL; RELTOL=1.0e-10; + else + options="nul"; + end, + end + + if typeof(G)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"linfn",1)) + end + if G.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"linfn",1)) + end + + if type(options)<>10|and(options<>["t","nul"]) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),"linfn",iopt,"""t"",""nul""")) + end + if type(PREC)<>1|size(PREC,"*")<>1|~isreal(PREC)|PREC<=0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be a positive scalar.\n"),"linfn",2)) + end + if type(RELTOL)<>1|size(RELTOL,"*")<>1|~isreal(RELTOL)|RELTOL<=0 then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be a positive scalar.\n"),"linfn",3)) + end + + + //recover realization + //******************* + [a,b,c,d]=abcd(G); + + + //SCALING + //******* ||B||.||C|| + // Scale A,B,C so that ||A||=||B||=||C||=1. With scale:= -----------, + // ||A|| + // and DD:=D/scale, AA:=A/||A||, BB:=B/||B||, CC:=C/||C||, we have + // -1 + // || G || = scale * || DD + CC (sI - AA) BB || + // + // From now on, the parameters A,B,C,D are scaled + + noa=norm(a,"inf"); nob=norm(b,"inf"); noc=norm(c,"inf"); nobc=nob*noc; + + if nobc==0, x=norm(d); return, end + + scale=nobc/noa; a=a/noa; b=b/nob; c=c/noc; d=d/scale; nd=norm(d); + + + //test the spectrum of A + //********************** + + s=real(spec(a)); + + if min(abs(s)) < RELTOL then + mprintf(gettext("%s: WARNING: the A matrix has eigenvalues near the imaginary axis.\n"),"linfn"); + end + + + //Search window initialization + //**************************** + // Initialize the search window [lower,upper] where `lower' and `upper' + // are lower and upper bounds on the Linf norm of G. When no such + // bounds are available, the window is arbitrarily set to [INIT_LOW,INIT_UPP] + // and the variables LOW and UPP keep record of these initial values so that + // the window can be extended if necessary. + + if max(s)*min(s) > 0 then + // A is stable or antistable: use associated Lyapunov equations + // to derive lower and upper bounds. + p=lyap(a',-b*b',"c"); + q=lyap(a,-c'*c,"c"); + s=sqrt(abs(spec(p*q))); + + lower=max(nd,max(s)); LOW=0; + upper=nd+2*sum(diag(s)); UPP=100*upper; + + else + if nd==0 then + lower=INIT_LOW; LOW=INIT_LOW; + else + lower=nd; LOW=0; + end + upper=INIT_UPP; UPP=INIT_UPP; + end + + + + //form the constant parts of the pencil (E,F) (see G. Robel). + //*********************************************************** + [na,na]=size(a); twona=2*na; + [p,m]=size(d); + nf=twona+min(m,p); //size of e and f + + // to ensure that D'*D is of size min(m,p), replace (a,b,c,d) by + // (a',c',b',d') if m>p + if m>p then + a=a'; d=d'; aux=b; b=c'; c=aux'; + end + + e=eye(2*na,2*na); e(nf,nf)=0; + nul=0; nul(na,na)=0; + f=[a,nul;-c'*c,-a']; f(nf,nf)=0; + dd=d'*d; Cd=c'*d; + + + //---------------------- + // BISECTION STARTS + //---------------------- + + while %t, + + ga=sqrt(lower*upper); //test point gamma = log middle of [lower,upper] + + if part(options,1)=="t" then + write(%io(2),[scale*lower,scale*ga,scale*upper],.. + "(''lower,current,upper = '',3e20.10)"); + end + + bga=b/ga; Cdga=Cd/ga; + f(1:na,twona+1:nf)=-bga; + f(na+1:twona,twona+1:nf)=Cdga; + f(twona+1:nf,1:nf)=[Cdga',bga',eye(dd)-dd/(ga**2)]; + + + // Test for generalized eigenvalues on the imaginary axis + // ------------------------------------------------------ + + [dist,frequ]=heval_test(e,f,RELTOL,"test"); + + if dist < RELTOL then + lower=ga; LOW=0; + // eigenvalue on the imaginary axis: gamma < ||G|| + else + upper=ga; UPP=100*upper; + // gamma > ||G|| + end + + + // Search window management: + //-------------------------- + // If the gamma-iteration runs into one of the initial arbitrary bounds + // LOW or UPP, extend the search window to allow for continuation + + if ga<10*LOW then + lower=LOW/10; LOW=lower; + end + // expand search window toward gamma<<1 + if ga>UPP/10 then + upper=UPP*10; UPP=upper; + end + // expand search window toward gamma>>1 + + + // Termination tests + //------------------ + + if lower > INFTY then + mprintf(gettext("%s: Controllable & observable mode(s) of A near the imaginary axis"),"linfn"); + x=scale*lower; + return; + else + if upper < 1.0e-10 then + x=scale*upper; + mprintf(gettext("%s: All modes of A are nearly nonminimal so that || G || is almost 0.\n"),"linfn"); + return; + else + if 1-lower/upper < PREC, + ga=sqrt(lower*upper); + x=scale*ga; + + // Compute all the frequencies achieving ||G|| + if lower<>0 then + bga=b/lower; Cdga=Cd/lower; + f(1:na,twona+1:nf)=-bga; + f(na+1:twona,twona+1:nf)=Cdga; + f(twona+1:nf,1:nf)=[Cdga',bga',eye(dd)-dd/(lower**2)]; + [dist,frequ]=heval_test(e,f,RELTOL,"freq"); + end + if frequ==[] then + mprintf(gettext("%s: The computed value of || G || may be inaccurate.\n"),"linfn"); + end + + // evaluate the condition of the eigenproblem of (e,f) near || G || + if part(options,1)=="c" then + gt=1.1*ga; + f=[a,nul,-b/gt;cc,at,Cd/gt;dc/gt,bt/gt,eye(dd)-dd/(gt**2)] + co=cond_test(e,f,frequ,RELTOL); + if co < RELTOL then + mprintf(gettext("%s: The computed value of || G || may be inaccurate.\n"),"linfn"); + end + end + //----------- + + return; + end, + end, + end + + end//end while + + +endfunction + + +function [dist,frequ]=heval_test(e,f,TOL,option); + //[dist,frequ]=heval_test(e,f,TOL,option); + // This procedure estimates the distance of the generalized spectrum + // of the pencil f - lambda e to the imaginary axis. Here e is always + // of the form diag(I_(nf-nz),0_nz). The distance is 0 whenever there are + // (nearly) infinite eigenvalues or eigenvalues of the form 0/0. + // + // The eigenvalues are computed via a generalized Schur decomposition + // of f - lambda e . Let (a(i),b(i)) : i=1..nf be the output of gspec. + // Three cases must be distinguished: + // * both a(i) and b(i) are << 1 -> singularity of the pencil + // * b(i)<<1 and a(i) close to 1 -> infinite eigenvalue + // * both a(i) and b(i) are close to 1 -> finite eigenvalue. + // + // Let nz denote the rank deficiency of e which is also the size of D'*D. + // For gamma > ||G||, the generalized spectrum of (e,f) consists of exactly + // nz infinite modes and nf-nz finite ones. By contrast, there may be + // additional singularities or infinite modes for ||D|| <= gamma <= ||G||, + // depending on whether ||D|| = ||G|| or ||D|| < ||G||. + // + // If ||D|| < ||G||, there are still exactly nz infinite modes for gamma in + // [ ||D|| , ||G|| ]. At gamma=||G||, some finite mode(s) hit the imaginary + // axis and their imaginary part omega is such that ||G(j omega)|| = ||G||. + // + // If ||D|| == ||G|| now, we always have ||G (infinity)|| = ||G|| + // and if moreover some pair (a(i),b(i)) is nearly (0,0), then + // || G (j omega) || = || G || for all omega's (direction along which G is + // all-pass). Note that G is all-pass iff there are nz pairs + // (a(i),b(i)) nearly equal to (0,0). Finally, finite modes which hit + // the imaginary axis still yield frequencies for which ||G|| is attained. + // + // Two options are available in this function: + // * When option='test', the function counts the number of finite modes. + // If less than nf-nz (nf=order of f), it concludes gamma <= ||G|| and returns + // dist=0. Otherwise, it estimates the distance of the finite spectrum + // min | Re(l_i) | + // to the imag. axis computed as --------------- where the l_i's denote + // max | l_i | + // the pencil finite eigenvalues. + // * With the option 'freq' (used for gamma = ||G||), it furthermore returns + // all frequencies for which ||G|| is attained. Infinite frequencies are + // denoted by -1 and if ||G(j omega)|| == ||G|| for all omega's, frequ=[-2]; + // + // + // Input: + // * (e,f): pencil + // * TOL: relative tolerance on the size of eigenvalue real parts. + // * option: 'test' or 'freq'. + // + // Output + // * dist: distance of the spectrum to the imaginary axis as defined above. + // * frequ: list of frequencies for which ||G|| is attained. + // + //! + //balancing + frequ=[]; evals=[]; + [f,xx]=balanc(f); + [nf,nf]=size(f); + nz=nf-sum(diag(e)); //rank deficiency of e + + + //Generalized Schur decomposition of the pencil (f,e) + //--------------------------------------------------- + [a,b]=spec(f,e); + + + if option=="test" then + //*********************************** + //Simple test and computation of dist + //*********************************** + + // Check that there are exactly nz infinite modes of (e,f) and compute dist + + nai=0; //nai: number of infinite or (0,0) modes (b(i) << 1) + for i=1:nf, + bi=abs(b(i)); + if bi < 100*TOL then + nai=nai+1; + else + evals=[evals,a(i)/bi]; + end + end + + if nai>nz then + dist=0; + else + dist=min(abs(real(evals)))/max(abs(evals)); + end + + else + //option = 'freq' + //************************************************* + //Compute the frequency for which ||G|| is attained + //************************************************* + + // Here gamma is appx equal to ||G||. Distinguish two cases: + // ||D|| < ||G|| and ||D|| = ||G||. + + if min(svd(f(nf-nz+1:nf,nf-nz+1:nf))) < TOL then + //----------------------------------------------- + // f(nf-nz+1:nf,nf-nz+1:nf)= I - (D'*D)/||G||**2 -> case ||D||=||G|| + + noa=max(abs(a)); na=0; //na -> # pairs (0,0) + frequ=[-1]; //||G|| is always attained for s=infinity in this case + for i=1:nf, + bi=b(i); + if abs(bi) < 100*TOL then + if abs(a(i)) < 100*TOL*noa, na=na+1; end + else + evals=[evals,a(i)/bi]; + end + end + + if na>0 then // G is all-pass along some direction + frequ=[-2]; + if na>=nz, mprintf(_("G is all-pass")); end + else + if evals<>[] then + maxabs=max(abs(evals)); + for i=1:max(size(evals)), + if abs(real(evals(i))) <= TOL*maxabs, + frequ=[frequ,abs(imag(evals(i)))]; + end + end, + end, + end + + + else + // case ||D|| < ||G|| + //------------------------ + + for i=1:nf, + bi=b(i); + if abs(bi) > 100*TOL, evals=[evals,a(i)/bi]; end + end + + maxabs=max(abs(evals)); + for i=1:max(size(evals)), + if abs(real(evals(i))) <= TOL*maxabs then + frequ=[frequ,abs(imag(evals(i)))]; + end + end + + end //endif + + frequ=list_set(frequ,1.0e-5); //eliminate redundancy in frequ + + end //endif + +endfunction + + +function [c]=cond_test(e,f,frequ,TOL); + //[c]=cond_test(e,f,frequ,TOL); + // This procedure returns a confidence index for the computed gamma = ||G|| + // at which some generalized eigenvalue(s) of (e,f) meets the imaginary + // axis. Specifically, it considers gamma := 1.1*computed value of ||G|| + // and computes how close (e,f) is to have imaginary eigenvalues + // for this gamma. If very close, this indicates (e,f) has generalized + // eigenvalues near the imaginary axis for all gamma's in an interval + // around ||G|| whence the computed value is likely to be inaccurate. + //! + [nf,nf]=size(f); + c=1; + + for i=1:max(size(frequ)), + s=svd(f-%i*frequ(i)*e); + c=min(c,s(nf)/s(1)); + if c < TOL then return; end + end + +endfunction + +function [l]=list_set(l,TOL); + //[l]=list_set(l,TOL); + // eliminates redundant elements in a list. Two entries are considered + // identical when their difference is smaller then TOL (in relative terms) + //! + nl=max(size(l)); + i=1; + + while i < nl, + entry=l(i); TOLabs=TOL*entry; + j=i+1; + while j <= nl, + if abs(l(j)-entry) <= TOLabs then + l=[l(1:j-1),l(j+1:nl)]; + nl=nl-1; + else + j=j+1; + end + end + i=i+1; + end +endfunction diff --git a/modules/cacsd/macros/lqe.bin b/modules/cacsd/macros/lqe.bin Binary files differnew file mode 100755 index 000000000..53bca16e2 --- /dev/null +++ b/modules/cacsd/macros/lqe.bin diff --git a/modules/cacsd/macros/lqe.sci b/modules/cacsd/macros/lqe.sci new file mode 100755 index 000000000..1bcdb0dc1 --- /dev/null +++ b/modules/cacsd/macros/lqe.sci @@ -0,0 +1,15 @@ +// 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 [K,X]=lqe(P21) + + [A,B1,C2,D21,xo,dom]=P21(2:7) + [kk,X]=lqr(syslin(dom,A',C2',B1',D21')); + K=kk'; +endfunction diff --git a/modules/cacsd/macros/lqg.bin b/modules/cacsd/macros/lqg.bin Binary files differnew file mode 100755 index 000000000..a565ee27d --- /dev/null +++ b/modules/cacsd/macros/lqg.bin diff --git a/modules/cacsd/macros/lqg.sci b/modules/cacsd/macros/lqg.sci new file mode 100755 index 000000000..7eeced6bb --- /dev/null +++ b/modules/cacsd/macros/lqg.sci @@ -0,0 +1,52 @@ +// 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 K=lqg(P,r) + // returns the (strictly proper) lqg (H2) controller + // for the augmented plant P + if and(typeof(P)<>["rational","state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"lqg",1)) + end + + if typeof(r)<>"constant"|~isreal(r) then + error(msprintf(gettext("%s: Wrong type for argument #%d: Real vector expected.\n"),"lqg",2)) + end + if size(r,"*")<>2 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: %d expected.\n"),"lqg",2,2)) + end + r=int(r); + if or(r<=0) then + error(msprintf(gettext("%s: Wrong values for input argument #%d: Elements must be positive.\n"),"lqg",2)) + end + + + if typeof(P)=="rational" then + P=tf2ss(P),flag=%f + else + flag=%t + end + + [A,B1,B2,C1,C2,D11,D12,D21,D22]=smga(P,r); + if norm(D11,1) <> 0 then + warning(msprintf(gettext("%s: %s is not zero! (set to zero)"),"lqg","D11")); + end + //if norm(D22,1) <> 0 then warning('lqg: D22 is not zero!');end + dom=P.dt; + if dom==[] then + warning(msprintf(gettext("%s: Input argument %d is assumed continuous time.\n"),"lqg",1)); + dom="c"; + end + P12=syslin(dom,A,B2,C1,D12); + Kc=lqr(P12); + P21=syslin(dom,A,B1,C2,D21); + Kf=lqe(P21); + P22=syslin(dom,A,B2,C2,D22); + K=obscont(P22,Kc,Kf); + if ~flag then K=ss2tf(K);end +endfunction diff --git a/modules/cacsd/macros/lqg2stan.bin b/modules/cacsd/macros/lqg2stan.bin Binary files differnew file mode 100755 index 000000000..b4579d413 --- /dev/null +++ b/modules/cacsd/macros/lqg2stan.bin diff --git a/modules/cacsd/macros/lqg2stan.sci b/modules/cacsd/macros/lqg2stan.sci new file mode 100755 index 000000000..16239dc20 --- /dev/null +++ b/modules/cacsd/macros/lqg2stan.sci @@ -0,0 +1,46 @@ +// 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 [P,m]=lqg2stan(P22,Q,R) + //P = standard plant for LQG control problem + //described by the triple (A,B,C) + // . + // x = Ax + w1 + Bu (resp x[n+1]= ... if dom='d') + // + // y = Cx + w2 + // + // cov(w1,w2)=R; + // + // mininize (x,u)'Q(x,u) + // + + flag=0; + P221=P22(1); + if P221(1)=="r" then + P22=tf2ss(P22);flag=1;end + P22=-P22; + [A,B,C,D22]=P22(2:5); + [nx,nu]=size(B); + [ny,nx]=size(C); + Qhalf=real(sqrtm(Q)); + Rhalf=real(sqrtm(R)); + B1=Rhalf(1:nx,:);D21=Rhalf(nx+1:nx+ny,:); + B2=B; + C1=Qhalf(:,1:nx);D12=Qhalf(:,nx+1:nx+nu); + C2=C; + D11=0*C1*B1; + dom=P22(7); + if dom==[] then + warning(msprintf(gettext("%s: Input argument #%d is assumed continuous time.\n"),"lqg2stan",1)); + end + P=syslin(dom,A,real([B1,B2]),real([C1;C2]),real([D11,D12;D21,D22])); + m=size(C2*B2); + if flag==1 then + P=ss2tf(P);end +endfunction diff --git a/modules/cacsd/macros/lqg_ltr.bin b/modules/cacsd/macros/lqg_ltr.bin Binary files differnew file mode 100755 index 000000000..d1a8a41b5 --- /dev/null +++ b/modules/cacsd/macros/lqg_ltr.bin diff --git a/modules/cacsd/macros/lqg_ltr.sci b/modules/cacsd/macros/lqg_ltr.sci new file mode 100755 index 000000000..5a2e4945e --- /dev/null +++ b/modules/cacsd/macros/lqg_ltr.sci @@ -0,0 +1,48 @@ +// 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 [kf,kc]=lqg_ltr(sl,mu,ro) + // [kf,kc]=lqg_ltr(sl,mu,ro) returns the Kalman gains for + // . + // x = a*x + b*u + l*w1 + // (sl) + // y = c*x + mu*I*w2 + // + // z = h*x + // + // Cost function: + // _inf + // J = E(/ [z(t)'*z(t) + ro**2*u(t)'*u(t)]dt) + // lqg / + // -0 + // The lqg/ltr approach looks for L,mu,H,ro such that: + //J(lqg) = J(freq) where + // _+oo * * * + // J = / tr[S W W S ] + tr[T T]dw + // freq / + // -0 + // and + // S = (I + G.K)^(-1) + // T = G.K.(I+G.K)^(-1) + // Inputs: + //-- sl linear system in state-space form (syslin list) + //-- mu , ro real positive numbers chosen ``small enough'' + //outputs: + //-- kf , kc = controller and observer Kalman gains. + //! + + [m,p]=size(sl); + [a,b,c,d]=abcd(sl); + r1=c'*c,r2=ro**2*eye(p,p), + q=b*b',r=mu**2*eye(m,m), + // kc=lqr(a,b,r1,r2,'c'), + // kf=lqe(a,c,q,r,'c') + kc=lqr(syslin("c",a,b,c,ro*eye(p,p))); + kf=lqe(syslin("c",a,b,c,mu*eye(m,m))); +endfunction diff --git a/modules/cacsd/macros/lqr.bin b/modules/cacsd/macros/lqr.bin Binary files differnew file mode 100755 index 000000000..2e30e3e93 --- /dev/null +++ b/modules/cacsd/macros/lqr.bin diff --git a/modules/cacsd/macros/lqr.sci b/modules/cacsd/macros/lqr.sci new file mode 100755 index 000000000..2d48ca8e4 --- /dev/null +++ b/modules/cacsd/macros/lqr.sci @@ -0,0 +1,108 @@ +// 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 [K,X]=lqr(P12) + //lqr gain for full-state LQ problem + //(discrete or continuous) + // discrete continuous + // |I 0 0| | A 0 B | |I 0 0| | A 0 B | + // z|0 A' 0| - |-C'C I -S'| s |0 I 0| - |-C'C -A' -S' | + // |0 B' 0| | S 0 D'D| |0 0 0| | S -B' D'D| + if typeof(P12)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"lqr",1)) + end + + [A,B2,C1,D12]=P12(2:5); + Q=C1'*C1;R=D12'*D12;S=D12'*C1; + [n,nu]=size(B2); + [ny,n]=size(C1); + if P12(7) == [] then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Time domain must be ''c'' or ''d''.\n"),"lqr",1)) + elseif P12(7) == "c" + Z=0*A;I=eye(A);O=zeros(n,nu); + bigE=[I,Z,O; ... + Z,I,O; ... + zeros(nu,2*n+nu)]; + + bigA=[A ,Z, B2; ... + -Q ,-A',-S'; ... + S ,B2', R]; + Ri=inv(R); + Left=[I, Z, -B2*Ri; + Z, I, S'*Ri; + zeros(nu,2*n), Ri]; + LA=Left*bigA;LE=Left*bigE;N=1:2*n; + //[wsmall,ks1]=schur(LA(N,N),LE(N,N),'c'); + [wsmall,ks1]=schur(LA(N,N),"c"); + if ks1<>n then + error(msprintf(gettext("%s: Stable subspace is too small.\n"),"lqr")); + end + X12=wsmall(1:n,1:n);phi12=wsmall(n+1:$,1:n);X=phi12/X12; + if rcond(X12)< 1.d-5 then + warning(msprintf(gettext("%s: Bad conditionning.\n"),"lqr")); + end + K=-Ri*(B2'*X+S); + return; + ////////////////////////////// + // Other implementation ... // + ////////////////////////////// + //[Q,Z,Qd,Zd,numbeps,numbeta]=kroneck(bigE,bigA); + //[w,ks]=schur(bigA,bigE,'c'); + //if ks<>n then error('lqr: stable subspace too small!');end + //ws=w(:,1:n); + //X12=ws(1:n,:); + //phi12=ws(n+1:2*n,:); + //u12=ws(2*n+1:2*n+nu,:); + //if rcond(X12)< 1.d-5 then warning('lqr: bad conditionning!');end + //K=u12/X12; + //X=phi12/X12; + //return + elseif P12(7) == "d" | type(P12(7))==1 + I=eye(A);Z=0*I; + Q=C1'*C1;R=D12'*D12;S=D12'*C1; + bigE=[I,Z,0*B2; ... + Z,A',0*B2; ... + 0*B2',-B2',0*B2'*B2]; + + bigA=[A,Z, B2; ... + -Q ,I, -S'; ... + S, 0*B2', R]; + + Ri=inv(R); + + Left=[I, Z, -B2*Ri; ... + Z, I, S'*Ri; ... + zeros(nu,2*n), Ri]; + LA=Left*bigA;LE=Left*bigE;N=1:2*n; + [wsmall,ks1]=schur(LA(N,N),LE(N,N),"d"); + if ks1<>n then + error(msprintf(gettext("%s: Stable subspace is too small.\n"),"lqr")); + end + X12=wsmall(1:n,1:n);phi12=wsmall(n+1:$,1:n);X=phi12/X12; + if rcond(X12)< 1.d-5 then + warning(msprintf(gettext("%s: Bad conditionning.\n"),"lqr")); + end + K=-pinv(B2'*X*B2+R)*(B2'*X*A+S); + return + //////////////////// + // Other form ... // + //////////////////// + //[w,ks]=schur(bigA,bigE,'d'); + //if ks<>n then error('lqr: stable subspace too small!');end + //ws=w(:,1:n); + //X12=ws(1:n,:); + //phi12=ws(n+1:2*n,:); + //u12=ws(2*n+1:2*n+nu,:); + //if rcond(X12)< 1.d-5 then warning('lqr: bad conditionning!');end + //K=u12/X12; + //X=phi12/X12; + //return + end + +endfunction diff --git a/modules/cacsd/macros/lyap.bin b/modules/cacsd/macros/lyap.bin Binary files differnew file mode 100755 index 000000000..267e9c733 --- /dev/null +++ b/modules/cacsd/macros/lyap.bin diff --git a/modules/cacsd/macros/lyap.sci b/modules/cacsd/macros/lyap.sci new file mode 100755 index 000000000..c1a2d7a20 --- /dev/null +++ b/modules/cacsd/macros/lyap.sci @@ -0,0 +1,24 @@ +// 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 X = lyap(A,C,flag) + // solve A'*X+X*A=C if flag=='c' or A'*X*A-X=C if flag=='d' + if argn(2)<>3 then + error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"),"lyap",3)) + end + flag=part(flag,1) + if flag=="c" then + flag=[0 0], + elseif flag=="d" then + flag=[1 0], + else + error(msprintf(gettext("%s: Wrong value for input argument #%d: ""c"" or ""d"" expected.\n"), "lyap", 3)); + end + X=linmeq(2,A,C,flag) +endfunction diff --git a/modules/cacsd/macros/m_circle.bin b/modules/cacsd/macros/m_circle.bin Binary files differnew file mode 100755 index 000000000..5c0fed582 --- /dev/null +++ b/modules/cacsd/macros/m_circle.bin diff --git a/modules/cacsd/macros/m_circle.sci b/modules/cacsd/macros/m_circle.sci new file mode 100755 index 000000000..be0b2ebc0 --- /dev/null +++ b/modules/cacsd/macros/m_circle.sci @@ -0,0 +1,57 @@ +// 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 []=m_circle(gain) + //this function is obsolete, superseeded by hallchart. + [lhr,rhs]=argn(0) + // + d36=11; + if rhs<1 then + gain=[-12 -8 -6 -5 -4 -3 -2 -1.4 -1 -.5 0.25 0.5 0.7 1 1.4 .. + 2 2.3 3 4 5 6 8 12] + else + gain=matrix(gain,1,prod(size(gain))) + end + // + titre="isogain contours for y/(1+y)" + l10=log(10); + // + lambda=exp(l10*gain/20) + rayon=lambda./(lambda.*lambda-ones(lambda)) + centre=-lambda.*rayon + rayon=abs(rayon) + rect=[min(centre-rayon),min(-rayon),max(centre+rayon),max(rayon)]; + // + fig=gcf(); + immediate_drawing=fig.immediate_drawing; + fig.immediate_drawing="off"; + + ax=gca(); + llrect=xstringl(0,0,"1") + hx=llrect(3); + // + for i=1:prod(size(gain)) + sgn=1;if 2*int(i/2)==i then sgn=-1,end + g=string(gain(i)),ng=length(g) + if gain(i)<0 then + w=0:0.03:%pi; + xx=centre(i)+rayon(i)*sin(%pi/3)+hx + xy=sgn*cos(%pi/3)*rayon(i) + else + xx=centre(i)-sin(%pi/3)*rayon(i)-hx*ng + xy=sgn*cos(-%pi/3)*rayon(i) + w=-%pi:0.03:0; + end; + n=prod(size(w)) + rf=centre(i)*ones(w)+rayon(i)*exp(%i*w); + xpoly([real(rf) real(rf($:-1:1))],[imag(rf) -imag(rf($:-1:1))]) + e=gce();e.foreground=3;e.clip_state="clipgrf" + end; + fig.immediate_drawing=immediate_drawing; + +endfunction diff --git a/modules/cacsd/macros/macglov.bin b/modules/cacsd/macros/macglov.bin Binary files differnew file mode 100755 index 000000000..e45341571 --- /dev/null +++ b/modules/cacsd/macros/macglov.bin diff --git a/modules/cacsd/macros/macglov.sci b/modules/cacsd/macros/macglov.sci new file mode 100755 index 000000000..76468d098 --- /dev/null +++ b/modules/cacsd/macros/macglov.sci @@ -0,0 +1,43 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [P,r]=macglov(Sl) + //[P,r]=macglov(Sl) + //Standard plant for the Glover-McFarlane problem: + // for this problem mu_optimal = 1-hankel_norm([N,M]) + // with [N,M]=LCF(Sl) (Normalized coprime factorization) + // gama_optimal = 1/sqrt(mu_optimal) + //! + if argn(2)<1 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected.\n"),.. + "macglov",1)) + end + + if and(typeof(Sl)<>["rational","state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"macglov",1)) + end + if Sl.dt<>"c" then + error(msprintf(gettext("%s: Wrong type for argument #%d: In continuous time expected.\n"),"macglov",1)) + end + flag=0; + if typeof(Sl)=="rational" then Sl=tf2ss(Sl),flag=1;end + [A,B,C,D]=abcd(Sl);[n,nb]=size(B);[nc,n]=size(C); + r=size(D); + [Z,H]=gfare(Sl); + R1=eye()+D*D'; + R12=sqrtm(R1); + Ap=A; + Bp=[-H*R12,B]; + Cp=[C;0*ones(nb,n);C]; + Dp=[R12,0*C*B; + 0*ones(nb,nc),eye(nb,nb); + R12,D]; + P=syslin("c",Ap,Bp,Cp,Dp); + if flag==1 then P=ss2tf(P);end +endfunction diff --git a/modules/cacsd/macros/markp2ss.bin b/modules/cacsd/macros/markp2ss.bin Binary files differnew file mode 100755 index 000000000..01cc4a9c0 --- /dev/null +++ b/modules/cacsd/macros/markp2ss.bin diff --git a/modules/cacsd/macros/markp2ss.sci b/modules/cacsd/macros/markp2ss.sci new file mode 100755 index 000000000..2082b3ec2 --- /dev/null +++ b/modules/cacsd/macros/markp2ss.sci @@ -0,0 +1,35 @@ +// 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 [Sl]=markp2ss(markpar,n,nout,nin) + // Given a set of n (matrix) Markov parameters stacked in the (row)-matrix + // markpar of size nout x (n*nin) markp2ss + // returns a state-space linear system Sl (syslin list) such that with: + // A=sl(2); B=sl(3); C=sl(4); + // C*B = markpar(1:nout,1:nin), + // C*A*B =marpar(1:nout,nin+1:2*nin),.... + // See also: pol2des + //! + + nmax=max(size(markpar)); + H=[];H(n*nout,n*nin)=0; + p=markpar; + l1=1:nout;k1=1; + H(l1,:)=p;kset=(nmax-nin+1):nmax;zeroing=0*ones(nout,nin); + for k=2:n; + l1=l1+nout*ones(l1); + k1=k1+nin; + p=markpar(:,k1:nmax);p(nout,nmax)=0; + H(l1,:)=p; + end; + [u,s,v,deg]=svd(H); + obs=u(:,1:deg);con=s*v(1:deg,:)'; + obstild=obs(nout+1:n*nout,:);obstild(n*nout,deg)=0; + Sl=syslin("c",obs'*obstild,con(1:deg,1:nin),obs(1:nout,:)) +endfunction diff --git a/modules/cacsd/macros/minreal.bin b/modules/cacsd/macros/minreal.bin Binary files differnew file mode 100755 index 000000000..6f6425702 --- /dev/null +++ b/modules/cacsd/macros/minreal.bin diff --git a/modules/cacsd/macros/minreal.sci b/modules/cacsd/macros/minreal.sci new file mode 100755 index 000000000..c8e15aead --- /dev/null +++ b/modules/cacsd/macros/minreal.sci @@ -0,0 +1,67 @@ +// 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 [a,b,c]=minreal(a,b,c,domaine,tol) + // + + [lhs,rhs]=argn(0) + select typeof(a) + case "state-space" then + if lhs<>1 then + error(msprintf(gettext("%s: Wrong number of output arguments: %d expected.\n"),"minreal",1)), + end; + select rhs + case 1 then + istol = %f; + case 2 then + istol = %t, + tol = b, + else + error(msprintf(gettext("%s: Wrong number of input arguments: %d or %d expected.\n"),"minreal",1,2)), + end; + [a,b,c,d,x0,dom] = a(2:7); + if dom == [] then + error(96,1); + end + domaine="c"; + if dom<>"c" then + domaine="d"; + end + case "constant" then + if lhs<>3 then + error(msprintf(gettext("%s: Wrong number of output arguments: %d expected.\n"),"minreal",3)), + end; + select rhs + case 4 then istol = %f + case 5 then istol = %t, + else + error(msprintf(gettext("%s: Wrong number of input arguments: %d or %d expected.\n"),"minreal",4,5)); + end; + else + error(91,1); + end; + // + wc = lyap(a', -b*b', domaine); + wo = lyap(a, -c'*c, domaine); + if ~istol then + [r,n] = equil1(wc,wo); + else + [r,n] = equil1(wc,wo,tol); + end; + n1 = n(1); + ri = inv(r); + r = r(1:n1,:); + ri = ri(:,1:n1); + a = r*a*ri; + b = r*b; + c = c*ri; + if lhs == 1 then + a = syslin(dom,a,b,c,d,r*x0); + end +endfunction diff --git a/modules/cacsd/macros/minss.bin b/modules/cacsd/macros/minss.bin Binary files differnew file mode 100755 index 000000000..dc4015ee8 --- /dev/null +++ b/modules/cacsd/macros/minss.bin diff --git a/modules/cacsd/macros/minss.sci b/modules/cacsd/macros/minss.sci new file mode 100755 index 000000000..62f23730a --- /dev/null +++ b/modules/cacsd/macros/minss.sci @@ -0,0 +1,34 @@ +// 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 Slmin=minss(Sl,tol) + + [lhs,rhs]=argn(0) + + if typeof(Sl)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: State-space form expected.\n"),"minss",1)); + end + + [a,b,c,d,x0,dom]=Sl(2:7) + //observability + if rhs<2 then tol=1.d-10*norm([a;c],1),end + [nc,u1]=contr(a',c',tol) + u=u1(:,1:nc) + c=c*u;a=u'*a*u;b=u'*b,x0=u'*x0; + + //controllability + if rhs<2 then tol=1.d-10*norm([a,b],1),end + [no,u2]=contr(a,b,tol) + u=u2(:,1:no) + a=u'*a*u;b=u'*b;c=c*u + + //form the result + Slmin=syslin(dom,a,b,c,d,u'*x0) + //Would be nice to return U=U1*U2 +endfunction diff --git a/modules/cacsd/macros/names b/modules/cacsd/macros/names new file mode 100755 index 000000000..0209a03f3 --- /dev/null +++ b/modules/cacsd/macros/names @@ -0,0 +1,173 @@ +abcd +abinv +acf +arhnk +arl2 +arma2p +arma2ss +armac +armax +armax1 +arsimul +augment +balreal +bilin +black +bloc2exp +bloc2ss +bode +bode_asymp +bstap +cainv +calfrq +canon +ccontrg +cfspec +cls2dls +colinout +colregul +cont_frm +cont_mat +contrss +copfac +csim +ctr_gram +damp +dbphi +dcf +ddp +des2ss +des2tf +dhnorm +dscr +dsimul +dt_ility +dtsi +entropy +epred +equil +equil1 +evans +findABCD +findAC +findBDK +findR +findx0BD +flts +formatBlackTip +formatBodeMagTip +formatBodePhaseTip +formatGainplotTip +formatHallModuleTip +formatHallPhaseTip +formatNicholsGainTip +formatNicholsPhaseTip +formatNyquistTip +formatPhaseplotTip +formatSgridDampingTip +formatSgridFreqTip +formatZgridDampingTip +formatZgridFreqTip +fourplan +frep2tf +freson +fspec +fspecg +fstabst +g_margin +gainplot +gamitg +gcare +gfare +gfrancis +gtild +h2norm +h_cl +h_inf +h_inf_st +h_norm +hallchart +hankelsv +imrep2ss +inistate +invrs +invsyslin +kpure +krac2 +lcf +leqe +leqr +lft +lin +linf +linfn +lqe +lqg +lqg2stan +lqg_ltr +lqr +lyap +m_circle +macglov +markp2ss +minreal +minss +narsimul +nehari +nicholschart +noisegen +nyquist +nyquistfrequencybounds +obs_gram +obscont +observer +obsv_mat +obsvss +p_margin +parrot +pfss +phasemag +phaseplot +plzr +prbs_a +projsl +repfreq +ric_desc +riccati +routh_t +rowinout +rowregul +sdiff +sensi +sgrid +show_margins +sm2des +sm2ss +smga +solve +specfact +ss2des +ss2ss +ss2tf +ssrand +st_ility +stabil +statgain +svplot +sylv +sysconv +sysdiag +sysfact +syslin +syssize +tf2des +tf2ss +time_id +trfmod +trianfml +trisolve +trzeros +ui_observer +unobs +zeropen +zgrid diff --git a/modules/cacsd/macros/narsimul.bin b/modules/cacsd/macros/narsimul.bin Binary files differnew file mode 100755 index 000000000..20960114d --- /dev/null +++ b/modules/cacsd/macros/narsimul.bin diff --git a/modules/cacsd/macros/narsimul.sci b/modules/cacsd/macros/narsimul.sci new file mode 100755 index 000000000..177a863a8 --- /dev/null +++ b/modules/cacsd/macros/narsimul.sci @@ -0,0 +1,143 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) ENPC - +// +// 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 z=narsimul(x1,x2,x3,x4,x5,x6,x7,x8) + //function z=narsimul(a,b,d,sig,u,up,yp,ep) + // or + // function z=arsimul(ar,u,up,yp,ep) + // + // Armax simulation using rtitr + // A(z)= Id+a1*z+...+a_r*z^r; ( r=0 => A(z)=Id) + // B(z)= b0+b1*z+...+b_s z^s; ( s=-1 => B(z)=0) + // D(z)= Id+d1*z+...+d_t z^t; ( t=0 => D(z)=Id) + // z et e sont a valeurs dans dans R^n et u dans R^m + // Auteur : J-Ph. Chancelier ENPC Cergrene + // + // Copyright Enpc + + [lhs,rhs]=argn(0) + // switch to ar representation + if type(x1)==1 then + if rhs < 5 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"narsimul",5,8)); + end; + ar=armac(x1,x2,x3,size(x1,"r"),size(x5,"r"),x4); + select rhs + case 5 then + z=narsimul(ar,x5); + case 6 then + z=narsimul(ar,x5,x6); + case 7 then + z=narsimul(ar,x5,x6,x7); + case 8 then + z=narsimul(ar,x5,x6,x7,x8); + end + elseif typeof(x1)== "ar" then // Here the call is always arsimul(ar,....) + if rhs < 2|rhs>5 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"),"narsimul",2,5)); + end; + + a=x1("a");b=x1("b");d=x1("d");sig=x1("sig"); + u=x2; + [mmu,Nu]=size(u); + if mmu<>x1("nu") then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: "+.. + "Number of rows of #%d are incompatible with #%d argument.\n"),.. + "narsimul",1,2,2,1)); + end; + // dimensions + [al,ac]=size(a);adeg=int(ac/al); + [dl,dc]=size(d);ddeg=int(dc/dl); + [bl,bc]=size(b);[mmu,Nu]=size(u);bdeg=int(bc/mmu); + // quelques tests a faire : bl=al=dl, + // <i>deg*<i>l=<i>c, pour i=a,b,d + // + // On genere d'abord y(k) solution de : A(z^-1)y(k)=B^(z-1)u(k) + s=poly(0,"s"); + // Build polynomial matrix A(s) + mata= a*((s.^[adeg-1:-1:0]).*.eye(al,al))'; + // Build polynomial matrix B(s) + matb= b*((s.^[bdeg-1:-1:0]).*.eye(mmu,mmu))'; + // + num=matb*s**(adeg-1) + den=mata*s**(bdeg-1); + // Using past values + // yp doit etre de taille (al,(adeg-1)) + // up doit etre de taille (al,(bdeg-1)) + // ep doit etre de taille (al,(adeg-1)) + // + if rhs <=3 then + up=0*ones(mmu,(bdeg-1)); + else + up=x3 + if size(up,1)<>mmu then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same row dimensions expected.\n"),"narsimul",2,3)) + end + if size(up,2)<>bdeg-1, + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: "+.. + "Number of columns of #%d are incompatible with #%d argument.\n"),.. + "narsimul",1,3,3,1)); + end + end + if rhs <=4 then + yp=0*ones(al,(adeg-1)); + else + yp=x4 + if size(yp,1)<>al then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: "+.. + "Number of rows of #%d are incompatible with #%d argument.\n"),.. + "narsimul",1,4,4,1)); + end + if size(yp,2)<>(adeg-1) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: "+.. + "Number of columns of #%d are incompatible with #%d argument.\n"),.. + "narsimul",1,4,4,1)); + end + end + if rhs <=5, + ep=0*ones(al,(ddeg-1)); + else + ep=x5 + if size(ep,1)<>al then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: "+.. + "Number of rows of #%d are incompatible with #%d argument.\n"),.. + "narsimul",1,5,5,1)); + end + if size(ep,2)<>(adeg-1) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: "+.. + "Number of columns of #%d are incompatible with #%d argument.\n"),.. + "narsimul",1,5,5,1)); + end + + end; + // + degnum=max(degree(den)); + yp=[0*ones(al,degnum+1-adeg),yp(:,(adeg-1):-1:1)]; + up=[0*ones(mmu,degnum+1-bdeg),up(:,(bdeg-1):-1:1)]; + y=rtitr(num,den,u,up,yp); + // truncate the solution to only keep y_1,..y_Nu + // (if b0=0 rtitr computes y_{Nu+1}) + y=y(:,1:Nu); + // Generate bru such that A(z^-1)bru= D(z^-1) sig*e(t) + // Build polynomial matrix D(s) + matd= d*((s.^[ddeg-1:-1:0]).*.eye(al,al))'; + num=matd*s**(adeg-1) + den=mata*s**(ddeg-1); + degnum=max(degree(den)); + ep=[0*ones(al,degnum+1-ddeg),ep(:,(ddeg-1):-1:1)]; + // Normal noise + br=sig*rand(al,Nu,"normal") + bru=rtitr(num,den,br,ep,0*ones(ep)); + // z(k) = y(k) + bru(k) + z=y+bru(:,1:Nu); + else + error(msprintf(gettext("%s: Wrong type for input argument #%d: %s data structure expected.\n"),"narsimul",1,"arma")); + end; +endfunction diff --git a/modules/cacsd/macros/nehari.bin b/modules/cacsd/macros/nehari.bin Binary files differnew file mode 100755 index 000000000..825004553 --- /dev/null +++ b/modules/cacsd/macros/nehari.bin diff --git a/modules/cacsd/macros/nehari.sci b/modules/cacsd/macros/nehari.sci new file mode 100755 index 000000000..8151bf941 --- /dev/null +++ b/modules/cacsd/macros/nehari.sci @@ -0,0 +1,77 @@ +// 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 [x]=nehari(r,tol) + // [x]=nehari(R,tol) returns the Nehari approximant of R. + // R = linear system in state-space representation (syslin list) + //- R is strictly proper and - R~ is stable (i.e. R is antistable). + // || R - X ||oo = min || R - Y ||oo + // Y in Hoo + //! + + if argn(2)<1 then + error(msprintf(gettext("%s: Wrong number of input argument(s): At least %d expected.\n"),.. + "nehari",1)) + end + + if typeof(r)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"nehari",1)) + end + if r.dt==[] then + warning(msprintf(gettext("%s: Input argument #%d is assumed continuous time.\n"),"nehari",1)); + r.dt="c" + end + if r.dt<>"c" then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Continuous time system expected.\n"),"nehari",1)) + end + // + if argn(2)==1 then + tol=1e-6 + else + if type(tol)<>1|size(tol,"*")<>1 then + error(msprintf(gettext("%s: Wrong type for input argument: Scalar expected.\n"),"nehari",2)) + end + if ~isreal(tol)|tol<=0 then + error(msprintf(gettext( "%s: Input argument #%d must be strictly positive.\n"),"nehari",2)) + end + end; + + //norm of Hankel operator + //----------------------- + nk=nophkel(r),nn=nk+tol, + r.B=r.B/nn, + //best approx. + //------------ + xo=-obs_gram(r),xc=-ctr_gram(r), + w=inv(eye()-xo*xc), + [m,k,n]=size(r),m=m(1), + [a,b,c]=abcd(r),o=0*ones(a), + ax=[a,o,o;o,a,-w'*b*b';o,o,-a'-w*xo*b*b'], + bx=[b;w'*b;w*xo*b],cx=[c,-c,0*ones(m,n)], + x=syslin("c",ax,bx,cx*nn), + [y,x]=dtsi(x); + + +endfunction + +function [nk]=nophkel(sl,tol) + //[nk]=nophkel(sl,[tol]) : norm of Hankel operator + [lhs,rhs]=argn(0), + if rhs==1 then tol=1000*%eps,end, + if sl==0 then nk=0,return,end, + lf=spec(sl.A), + if min(abs(lf))<=tol then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Pure imaginary poles unexpected.\n"),"nehari",1)) + end, + if max(real(lf))<tol then nk=0,return,end, + sl=dtsi(sl); + lc=ctr_gram(sl),lo=obs_gram(sl), + vp=spec(lc*lo),vmax=max(real(vp)), + nk=sqrt(vmax) +endfunction diff --git a/modules/cacsd/macros/nicholschart.bin b/modules/cacsd/macros/nicholschart.bin Binary files differnew file mode 100755 index 000000000..040ca4719 --- /dev/null +++ b/modules/cacsd/macros/nicholschart.bin diff --git a/modules/cacsd/macros/nicholschart.sci b/modules/cacsd/macros/nicholschart.sci new file mode 100755 index 000000000..3172305e1 --- /dev/null +++ b/modules/cacsd/macros/nicholschart.sci @@ -0,0 +1,196 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 nicholschart(modules,args,colors) + + [lhs,rhs]=argn(0); + + l10=log(10); + ratio=%pi/180; + + fig=gcf(); + immediate_drawing=fig.immediate_drawing; + fig.immediate_drawing="off"; + + ax=gca(); + old_data_bounds = ax.data_bounds; + nc=size(ax.children,"*") + if nc==0 then + ax.data_bounds=[-360,-40;0,40]; + ax.axes_visible="on"; + ax.box="on"; + ax.tight_limits="on" + ax.title.text=_("Amplitude and phase contours of y/(1+y)") + ax.x_label.text=_("phase(y) (degree)"); + ax.y_label.text=_("magnitude(y) (dB)"); + else + ax.data_bounds(2,2)=max( ax.data_bounds(2,2),40) + end + ax.clip_state="clipgrf" + + phi_min=ax.data_bounds(1,1) + phi_max=ax.data_bounds(2,1) + mod_min=ax.data_bounds(1,2) + mod_max=ax.data_bounds(2,2) + + defaultArgs = [1 2 5 10 20 30 50 70 90 120 140 160 180]; + defaultModules=[mod_min:20:-35 -30 -25 -20 -15 -12 -9 -6 -3 -2 -1 -0.5 -0.25 -0.1 0 0.1 0.25 0.5 1 2.3 4 6 12]; + + + if exists("modules","local") == 0 | modules == [] then + modules=defaultModules + else + if type(modules)<>1|~isreal(modules) then + error(msprintf("%s: Wrong type for imput argument ""%s"": real floating point array expected\n"),"nicholschart","modules"); + end + modules=matrix(modules,1,-1) + end + if exists("args","local")==0 | args == [] then + args=defaultArgs + else + if type(args)<>1|~isreal(args) then + error(msprintf("%s: Wrong type for imput argument ""%s"": real floating point array expected\n"),"nicholschart","args"); + end + args=matrix(args,1,-1) + end + // + if exists("colors","local")==0 | colors == [] then + colors=[4 12]; + else + if type(colors)<>1|~isreal(colors) then + error(msprintf("%s: Wrong type for imput argument ""%s"": real floating point array expected\n"),"hallchart","colors"); + end + if size(colors,"*")==1 then + colors=colors*ones(1,2) + end + end + // convert args to radian and insure negative + args = -abs(args) * ratio; + + //initialize handles array for chart entities + chart_handles=[] + + // Replication bounds + k1=floor(phi_min/180) + k2=ceil(phi_max/180) + + //isogain curves: y as fixed gain and varying phase + //------------------------------------------------- + if modules<>[] then + w=[linspace(-%pi,-0.1,100) linspace(-0.1,0,80) ] + nw=size(w,"*") + for i = 1:prod(size(modules)), + att=modules(i); + y=10^(att/20)*exp(%i*w); + y(y==1)=[];//remove singular point if any + rf=y./(1-y); + [module, phi]=dbphi(rf) + //use symetry and period to extend the curve on [k1*180 k2*180] + p=[];m=[]; + S=[];cut=[] + for k=k1:k2-1 + if pmodulo(k,2)==0 then + p=[p cut k*180-phi($:-1:1)] + m=[m cut module($:-1:1)] + if att>0 then + str=msprintf("%.2gdB",att) + r=xstringl(0,0,str) + xstring(k*180-phi($)-r(3)/2,module($),str,0,0), + e=gce(); + e.font_foreground=colors(1) + S=[e S] + elseif att==0 then + l=find(module>mod_max-r(4),1) + if l<>[] then + xstring(k*180-phi(l-1),module(l-1),"0dB",0,0), + e=gce(); + e.font_foreground=colors(1) + S=[e S] + end + end + else + p=[p cut ((k+1)*180)+phi] + m=[m cut module] + if att<0 then + str=msprintf("%.2gdB",att) + r=xstringl(0,0,str) + xstring(p($)-r(3),m($),str,0,0), + e=gce(); + e.font_foreground=colors(1) + S=[e S] + end + end + cut=%nan + end + xpoly(p,m) + e=gce(); + e.foreground=colors(1), + e.line_style=7; + e.display_function = "formatNicholsGainTip"; + e.display_function_data = att; + + if size(S,"*")>1 then S=glue(S),end + chart_handles=[glue([S,e]),chart_handles]; + end; + end + + //isophase curves: y as fixed phase and varying gain + //------------------------------------------------- + + if args<>[] then + + eps=10*%eps; + for teta=args, + //w = teta produce a 0 gain and consequently a singularity in module + if teta < -%pi/2 then + last=teta-eps, + else + last=teta+eps, + end; + //use logarithmic discretization to have more mesh points near low modules + w=real(logspace(log10(-last),log10(170*ratio),150)) + w=-w($:-1:1) + + n=prod(size(w)); + module=real(20*log((sin(w)*cos(teta)/sin(teta)-cos(w)))/l10) + w=w/ratio + //use symetry and period to extend the curve on [k1*180 k2*180] + p=[];m=[]; + for k=k1:k2-1 + if pmodulo(k,2)==0 then + p=[p %nan k*180-w($:-1:1)] + m=[m %nan module($:-1:1)] + else + p=[p %nan ((k+1)*180)+w] + m=[m %nan module] + end + end + xpoly(p,m) + e=gce(); + e.foreground=colors(2); + e.line_style=7; + e.display_function = "formatNicholsPhaseTip"; + e.display_function_data = teta * 180 / %pi; + chart_handles=[e chart_handles] + end; + end + chart_handles=glue(chart_handles) + //reorder axes children to make chart drawn before the black curves if any + for k=1:nc + swap_handles(ax.children(k),ax.children(k+1)) + end + + fig.immediate_drawing=immediate_drawing; + + // reset data_bounds + if rhs == 0 then + ax.data_bounds=[-360,-40;0,40]; + else + ax.data_bounds = old_data_bounds; + end +endfunction diff --git a/modules/cacsd/macros/noisegen.bin b/modules/cacsd/macros/noisegen.bin Binary files differnew file mode 100755 index 000000000..545517826 --- /dev/null +++ b/modules/cacsd/macros/noisegen.bin diff --git a/modules/cacsd/macros/noisegen.sci b/modules/cacsd/macros/noisegen.sci new file mode 100755 index 000000000..20bfd5ef1 --- /dev/null +++ b/modules/cacsd/macros/noisegen.sci @@ -0,0 +1,24 @@ +// 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 noisegen(pas,Tmax,sig) + // This function returns in the calling env + // a macro [b]=Noise(t) + // Noize(t) is a piecewise constant function [k*pas,(k+1)*pas] + //The value on each constant interval are random values from + // i.i.d Gaussian variables of standard deviation sig. + // The function is constant for t<=0 and t>=Tmax. + //! + + dua_g=sig*rand(0:pas:Tmax,"n"); + [nn1,nn2]=size(dua_g); + deff("[b]=Noise(t)","b=dua_g(min(max((t/"+string(Tmax)+... + ")*"+string(nn2)+",1),"+string(nn2)+"))"); + [dua_g,Noise]=resume(dua_g,Noise); +endfunction diff --git a/modules/cacsd/macros/nyquist.bin b/modules/cacsd/macros/nyquist.bin Binary files differnew file mode 100755 index 000000000..19033e592 --- /dev/null +++ b/modules/cacsd/macros/nyquist.bin diff --git a/modules/cacsd/macros/nyquist.sci b/modules/cacsd/macros/nyquist.sci new file mode 100755 index 000000000..10fb2dda3 --- /dev/null +++ b/modules/cacsd/macros/nyquist.sci @@ -0,0 +1,275 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 1984-2011 - INRIA - Serge STEER +// 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 nyquist(varargin) + // Nyquist plot + //! + rhs=size(varargin); + + if rhs == 0 then + //Hall chart as a grid for nyquist + s=poly(0,"s"); + Plant=syslin("c",16000/((s+1)*(s+10)*(s+100))); + //two degree of freedom PID + tau=0.2;xsi=1.2; + PID=syslin("c",(1/(2*xsi*tau*s))*(1+2*xsi*tau*s+tau^2*s^2)); + nyquist([Plant;Plant*PID],0.5,100,["Plant";"Plant and PID corrector"]); + hallchart(colors=color("light gray")*[1 1]) + //move the caption in the lower rigth corner + ax=gca();Leg=ax.children(1); + Leg.legend_location="in_upper_left"; + return; + end + + symmetry=%t + if type(varargin(rhs))==4 then //symmetrization flag + symmetry=varargin(rhs) + rhs=rhs-1 + end + if type(varargin(rhs))==10 then + comments=varargin(rhs); + rhs=rhs-1; + else + comments=[]; + end + fname="nyquist";//for error messages + fmax=[]; + if or(typeof(varargin(1))==["state-space" "rational"]) then + //sys,fmin,fmax [,pas] or sys,frq + refdim=1; //for error message + sltyp=varargin(1).dt; + if rhs==1 then + [frq,repf,splitf]=repfreq(varargin(1),1d-3,1d3); + elseif rhs==2 then //sys,frq + if size(varargin(2),2)<2 then + error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"),fname,2,1)) + end + [frq,repf]=repfreq(varargin(1:rhs)); + elseif or(rhs==(3:4)) then //sys,fmin,fmax [,pas] + [frq,repf,splitf]=repfreq(varargin(1:rhs)); + else + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),fname,1,5)) + end + elseif type(varargin(1))==1 then + //frq,db,phi [,comments] or frq, repf [,comments] + refdim=2; + sltyp="x"; + splitf=[]; + splitf=1; + select rhs + case 2 then //frq,repf + frq=varargin(1); + repf=varargin(2); + if size(frq,2)<2 then + error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"),fname,1,1)) + end + if size(frq,2)<>size(varargin(2),2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),fname,1,2)) + end + + case 3 then //frq,db,phi + frq=varargin(1); + if size(frq,2)<>size(varargin(2),2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),fname,1,2)); + end + if size(frq,2)<>size(varargin(3),2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),fname,1,3)); + end + repf=exp(log(10)*varargin(2)/20 + %pi*%i/180*varargin(3)); + + else + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),fname,2,4)) + end + else + error(msprintf(_("%s: Wrong type for input argument #%d: Linear dynamical system or row vector of floats expected.\n"),fname,1)); + end; + if size(frq,1)==1 then + ilf=0; + else + ilf=1; + end + + [mn,n]=size(repf); + if and(size(comments,"*")<>[0 mn]) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same number of elements expected.\n"),fname,refdim,rhs+1)); + end + // + + repi=imag(repf); + repf=real(repf); + + // computing bounds of graphic window + mnx=min(-1,min(repf));// to make the critical point visible + mxx=max(-1,max(repf)); + + if symmetry then + mxy=max(0,max(abs(repi))); + mny=min(0,-mxy); + else + mxy=max(0,max(repi)); + mny=min(0,min(repi)); + end + dx=(mxx-mnx)/30; + dy=(mxy-mny)/30; + rect=[mnx-dx,mny-dy;mxx+dx,mxy+dy]; + + fig=gcf(); + immediate_drawing=fig.immediate_drawing; + fig.immediate_drawing="off"; + + ax=gca(); + if ax.children==[] then + ax.data_bounds=rect; + ax.axes_visible="on"; + ax.grid=color("lightgrey")*ones(1,3) + ax.title.text=_("Nyquist plot"); + if sltyp=="c" then + ax.x_label.text=_("Re(h(2iπf))"); + ax.y_label.text=_("Im(h(2iπf))"); + elseif sltyp=="x" then + ax.x_label.text=_("Re"); + ax.y_label.text=_("Im"); + else + ax.x_label.text=_("Re(h(exp(2iπf*dt)))"); + ax.y_label.text=_("Im(h(exp(2iπf*dt)))"); + end + else + rect= ax.data_bounds + mnx=rect(1,1); + mxx=rect(2,1) + mny=rect(1,2) + mxy=rect(2,2) + end + + // drawing the curves + splitf($+1)=n+1; + + ksplit=1;sel=splitf(ksplit):splitf(ksplit+1)-1; + R=[repf(:,sel)]; I=[repi(:,sel)]; + F=frq(:,sel); + for ksplit=2:size(splitf,"*")-1 + sel=splitf(ksplit):splitf(ksplit+1)-1; + R=[R %nan(ones(mn,1)) repf(:,sel)]; + I=[I %nan(ones(mn,1)) repi(:,sel)]; + F=[F %nan(ones(size(frq,1),1)) frq(:,sel)]; + end + Curves=[] + + kf=1 + if symmetry then + for k=1:mn + xpoly([R(k,:) R(k,$:-1:1)],[I(k,:) -I(k,$:-1:1)]); + e=gce();e.foreground=k; + e.display_function = "formatNyquistTip"; + e.display_function_data = [F(kf,:) -1*F(kf,$:-1:1)]; + Curves=[Curves,e]; + kf=kf+ilf; + end + else + for k=1:mn + xpoly(R(k,:),I(k,:)); + e=gce();e.foreground=k; + e.display_function = "formatNyquistTip"; + e.display_function_data = F(kf,:); + Curves=[Curves,e]; + kf=kf+ilf; + end + end + clear R I + + kk=1;p0=[repf(:,kk) repi(:,kk)];ks=1;d=0; + dx=rect(2,1)-rect(1,1); + dy=rect(2,2)-rect(1,2); + dx2=dx^2; + dy2=dy^2; + + // collect significant frequencies along the curve + //------------------------------------------------------- + Ic=min(cumsum(sqrt((diff(repf,1,"c").^2)/dx2+ (diff(repi,1,"c").^2)/dy2),2),"r"); + kk=1; + L=0; + DIc=0.2; + while %t + ksup=find(Ic-L>DIc); + if ksup==[] then break,end + kk1=min(ksup); + L=Ic(kk1); + Ic(1:kk1)=[]; + kk=kk+kk1; + + if min(abs(frq(:,ks($))-frq(:,kk))./abs(frq(:,kk)))>0.001 then + if min(sqrt(((repf(:,ks)-repf(:,kk)*ones(ks)).^2)/dx2+.. + ((repi(:,ks)-repi(:,kk)*ones(ks)).^2)/dy2)) >DIc then + ks=[ks kk]; + d=0; + end + end + end + if ks($)~=n then + if min(((repf(:,ks(1))-repf(:,n)).^2)/dx2+((repi(:,ks(1))-repi(:,n)).^2)/dy2)>0.01 then + ks=[ks n]; + end + end + // display of parametrization (frequencies along the curve) + //------------------------------------------------------- + kf=1 + if ks($)<size(repf,2) then last=$;else last=$-1;end + for k=1:mn, + L=[]; + for kks=ks + xstring(repf(k,kks),repi(k,kks),msprintf("%-0.3g",frq(kf,kks)),0); + e=gce();e.font_foreground=k; + L=[e L]; + if symmetry&(abs(repi(k,kks))>mxy/20) then //not to overlap labels + xstring(repf(k,kks),-repi(k,kks),msprintf("%-0.3g",-frq(kf,kks)),0); + e=gce();e.font_foreground=k; + L=[e L]; + end + end + L=glue(L); + A=[]; + + if size(ks,"*")>1 then + dr=repf(k,ks(1:last)+1)-repf(k,ks(1:last)); + di=repi(k,ks(1:last)+1)-repi(k,ks(1:last)); + dd=1500*sqrt((dr/dx).^2+(di/dy).^2); + dr=dr./dd; + di=di./dd; + // we should use xarrows or xsegs here. + // However their displayed arrow size depends + // on the data bounds and we want to avoid this + if symmetry then + xx=[repf(k,ks(1:last)) repf(k,ks(last:-1:1))+dr($:-1:1) ; + repf(k,ks(1:last))+dr repf(k,ks(last:-1:1))] + yy=[repi(k,ks(1:last)) -repi(k,ks(last:-1:1))-di($:-1:1) ; + repi(k,ks(1:last))+di -repi(k,ks(last:-1:1))] + else + xx=[repf(k,ks(1:last)) ; + repf(k,ks(1:last))+dr] + yy=[repi(k,ks(1:last)); + repi(k,ks(1:last))+di] + end + xpolys(xx,yy) + //xarrows([repf(k,ks(1:last));repf(k,ks(1:last))+dr],.. + // [repi(k,ks(1:last));repi(k,ks(1:last))+di],1.5) + A=gce(); + A.children.arrow_size_factor = 1.5; + A.children.polyline_style = 4; + A.children.foreground=k; + end + + kf=kf+ilf; + glue([Curves(k) glue([L A])]); + + end; + + if comments<>[] then + legend(Curves, comments); + end + fig.immediate_drawing=immediate_drawing; +endfunction diff --git a/modules/cacsd/macros/nyquistfrequencybounds.bin b/modules/cacsd/macros/nyquistfrequencybounds.bin Binary files differnew file mode 100755 index 000000000..7ab44bdd0 --- /dev/null +++ b/modules/cacsd/macros/nyquistfrequencybounds.bin diff --git a/modules/cacsd/macros/nyquistfrequencybounds.sci b/modules/cacsd/macros/nyquistfrequencybounds.sci new file mode 100755 index 000000000..05cac62ae --- /dev/null +++ b/modules/cacsd/macros/nyquistfrequencybounds.sci @@ -0,0 +1,132 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2011 - INRIA - Serge Steer +// +// 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 [fmin,fmax]=nyquistfrequencybounds(H,bounds) + //find frequencies that reaches the nyquist bounds on real an imag part + + fname="nyquistFrequencyBounds" //for error messages + + if or(size(bounds)<>[2 2]) then + error(msprintf(_("%s: Wrong size for argument #%d: (%d,%d) expected.\n"),fname,2,2,2)) + end + if or(bounds(2,:)<bounds(1,:)) then + error(msprintf(_("%s: Wrong value for input argument #%d: second row must be greater than first one.\n"),fname,2)) + end + if and(typeof(H)<>["state-space" "rational"]) then + error(msprintf(_("%s: Wrong type for input argument #%d: Linear dynamical system expected.\n"),fname,1)) + end + if size(H,"*")<>1 then + error(msprintf(_("Wrong type for argument #%d: SISO expected.\n"),fname,1)) + end + + if typeof(H)=="state-space" then + H=ss2tf(H) + end + + dom=H.dt + if dom==[]|dom=="d" then dom=1,end + eps=1d-10 + + frq=[]; + orient=[] + if dom=="c" then + c=2*%i*%pi + function f=arg2freq(y) + f=y/c; + endfunction + Hr=(H+horner(H,-%s))/2; + Hi=(H-horner(H,-%s))/2; + else + c=2*%i*%pi*dom + function f=arg2freq(y) + f=log(y)/c; + endfunction + Hr=(H+horner(H,1/%z))/2; + Hi=(H-horner(H,1/%z))/2; + end + + // computing frequencies that make the nyquist locus to cross + // the real part lower bound + f=arg2freq(roots(numer(Hr-bounds(1,1)))); + f=real(f(real(f)>0&abs(imag(f)./abs(f))<eps)); + //keep only those that give imaginary parts inside the bounds + im=imag(repfreq(H,f)); + f=f(im<=bounds(2,2)&im>=bounds(1,2)) + if f<>[] then + orient=[orient imag(repfreq(derivat(Hr),f))<0] + frq=[frq;f]; + end + + // computing frequencies that make the nyquist locus to cross + // the real part upper bound + f=arg2freq(roots(numer(Hr-bounds(2,1)))); + f=real(f(real(f)>0&abs(imag(f)./abs(f))<eps)); + //keep only those that give imaginary parts inside the bounds + im=imag(repfreq(H,f)); + f=f(im<=bounds(2,2)&im>=bounds(1,2)) + if f<>[] then + orient=[orient imag(repfreq(derivat(Hr),f))>0] + frq=[frq;f]; + end + + // computing frequencies that make the nyquist locus to cross + // the imaginary part lower bound + f=arg2freq(roots(numer(Hi-%i*bounds(1,2)))); + f=real(f(real(f)>0&abs(imag(f)./abs(f))<eps)); + //keep only those that give real parts inside the bounds + re=real(repfreq(H,f)); + f=f(re<=bounds(2,1)&re>=bounds(1,1)) + if f<>[] then + orient=[orient real(repfreq(derivat(Hi),f))>0] + frq=[frq;f]; + end + + // computing frequencies that make the nyquist locus to cross + // the imaginary part upper bound + f=arg2freq(roots(numer(Hi-%i*bounds(2,2)))); + f=real(f(real(f)>0&abs(imag(f)./abs(f))<eps)); + //keep only those that give real parts inside the bounds + re=real(repfreq(H,f)); + f=f(re<=bounds(2,1)&re>=bounds(1,1)) + if f<>[] then + orient=[orient real(repfreq(derivat(Hi),f))<0] + frq=[frq;f]; + end + + if frq==[] then + //check if there is at least one point inside the bounds + r=repfreq(H,%pi) + if real(r)<bounds(1,1)|real(r)>bounds(2,1)|imag(r)<bounds(1,2)| ... + imag(r)>bounds(2,2) then + fmin=[];fmax=[] + else + fmin=0;fmax=%inf + end + else + //looking for the lowest frequency for which the locus enters the + //area and the highest for which the locus leaves it. + [frq,k]=gsort(frq,"g","i"); + orient=orient(k) + if ~orient(1) then + //locus starts inside the area + frq=[0;frq] + end + if orient($) then + //locus ends inside the area + frq=[frq;%inf] + end + + fmin=frq(1) + fmax=frq($) + + end + + +endfunction + diff --git a/modules/cacsd/macros/obs_gram.bin b/modules/cacsd/macros/obs_gram.bin Binary files differnew file mode 100755 index 000000000..2b46ac172 --- /dev/null +++ b/modules/cacsd/macros/obs_gram.bin diff --git a/modules/cacsd/macros/obs_gram.sci b/modules/cacsd/macros/obs_gram.sci new file mode 100755 index 000000000..25cf479e1 --- /dev/null +++ b/modules/cacsd/macros/obs_gram.sci @@ -0,0 +1,61 @@ +// 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 [go]=obs_gram(a,c,domaine) + + [lhs,rhs]=argn(0) + select typeof(a) + case "constant" then + if rhs<2 then error(39); end; + if rhs==2 then domaine="c"; end; + if and(domaine<>["d","c"]) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"), "obs_gram",3,"''d'', ''c''")); + end + [m,n]=size(a) + if m<>n then error(20,1),end + [mb,nb]=size(c);if nb<>n then error(60),end + case "state-space" then + if rhs>1 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected"),"obs_gram",1)), + end + [a,c,domaine]=a([2,4,7]) + if domaine==[] then + warning(msprintf(gettext("%s: Input argument #%d is assumed continuous time.\n"),"obs_gram",1)); + domaine="c"; + elseif type(domaine)==1 then + domaine="d", + end + [n,n]=size(a) + case "rational" then + if rhs>1 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected"),"obs_gram",1)), + end + a=tf2ss(a) + [a,c,domaine]=a([2,4,7]) + if domaine==[] then + warning(msprintf(gettext("%s: Input argument #%d is assumed continuous time.\n"),"obs_gram",1)); + domaine="c"; + elseif type(domaine)==1 then + domaine="d", + end + [n,n]=size(a) + else + if rhs==1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear dynamical system expected.\n"),"obs_gram",1)) + else + error(msprintf(gettext("%s: Wrong type of input argument #%d: Array of floating point numbers expected.\n"),"obs_gram",1)) + end + end; + // + s=spec(a) + if (domaine=="c"&max(real(s))>=0)|(domaine=="d"&max(abs(s))>=1) then + error(msprintf(gettext("%s: Wrong value for input argument #%d: Stable system expected.\n"),"obs_gram",1)); + end + go=lyap(a,-c'*c,domaine) +endfunction diff --git a/modules/cacsd/macros/obscont.bin b/modules/cacsd/macros/obscont.bin Binary files differnew file mode 100755 index 000000000..4bc623e12 --- /dev/null +++ b/modules/cacsd/macros/obscont.bin diff --git a/modules/cacsd/macros/obscont.sci b/modules/cacsd/macros/obscont.sci new file mode 100755 index 000000000..e79d6ec29 --- /dev/null +++ b/modules/cacsd/macros/obscont.sci @@ -0,0 +1,22 @@ +// 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 [K,r]=obscont(P,Kc,Kf) + //Returns the observer-based controller associated with a + //plant P=[A,B,C,D]. The full-state control gain is Kc and filter + //gain is Kf. A+B*Kc and A+C*Kf are assumed stable. + + [LHS,RHS]=argn(0) + [A,B,C,D]=abcd(P); + K=syslin(P(7),A+B*Kc+Kf*C+Kf*D*Kc,-Kf,Kc) + if LHS==1 then r=[];return;end + zro=0*Kc*Kf;I1=eye(Kc*B);I2=eye(C*Kf); + K=syslin(P(7),A+B*Kc+Kf*C+Kf*D*Kc,[-Kf,B+Kf*D],[Kc;-C-D*Kc],[zro,I1;I2,-D]); + r=size(D); +endfunction diff --git a/modules/cacsd/macros/observer.bin b/modules/cacsd/macros/observer.bin Binary files differnew file mode 100755 index 000000000..52e4285d4 --- /dev/null +++ b/modules/cacsd/macros/observer.bin diff --git a/modules/cacsd/macros/observer.sci b/modules/cacsd/macros/observer.sci new file mode 100755 index 000000000..65d884866 --- /dev/null +++ b/modules/cacsd/macros/observer.sci @@ -0,0 +1,96 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [Obs,U,m]=observer(Sys,flag,alfa) + //Obs=observer for (observable part of) linear system Sys + //Obs is a linear system with matrices [Ao,Bo,Identity]. + //where Ao is no x no, Bo is no x (nu+ny) and Co is no x no + //and no=nx-m; + //input to Obs is [u,y] (assuming Sys: dotx=A x + Bu, y=Cx + Du) + //output of Obs is: + // xhat=estimate of x modulo unobservable subsp. (case 'pp') + // or + // xhat=estimate of x modulo unstable unobservable subsp. (case 'st') + // + //case flag='st': + // z=H*x can be estimated with stable observer iff H*U(:,1:m) = 0 + // assignable poles of the observer are set to alfa(1),alfa(2),... + // + //case flag='pp': + // z=H*x can be estimated with given error spectrum iff H*U(:,1:m)=0 + //all poles of the observer are assigned and set to alfa(1),alfa(2),... + // + //If H satifies the constraint: H*U(:,1:m)=0 (ker(H) contains unobs-subsp + //of Sys) one has H*U=[0,H2] and the observer for + // z=H*x is is H2*Obs with H2=H*U(:,m+1:nx) i.e. Co, the C-matrix of the + // observer for H*x, is Co=H2. + // + //EXAMPLE: + // nx=5;nu=1;ny=1;un=3;us=2;Sys=ssrand(ny,nu,nx,list('dt',us,us,un)); + // nx=5 states, nu=1 input, ny=1 output, + // un=3 unobservable states, us=2 of them unstable. + // [Obs,U,m]=observer(Sys); Stable observer (default) + // W=U';H=W(m+1:nx,:);[A,B,C,D]=abcd(Sys); //H*U=[0,eye(no,no)]; + // Sys2=ss2tf(syslin('c',A,B,H)) //Transfer u-->z + // Idu=eye(nu,nu);ss2tf(Obs*sysdiag(Idu,Sys)*[Idu;Idu]) + // Transfer u-->[u;u]-->w=[u;y=Sys*u]-->Obs*w i.e. u-->output of Obs + // this transfer must equal Sys2, the u-->z transfer (H2=eye). + + [LHS,RHS]=argn(0); + if typeof(Sys)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"observer",1)) + end + + [nx,nx]=size(Sys.A); + td=Sys.dt;x0=Sys.X0; + + if RHS<>2 then [m1,m2,U,sl2]=dt_ility(Sys);end + if RHS==1 then + flag="st";alfa=-ones(1,nx); + end + if RHS==2 then + //poles are not given-->set to -ones + alfa=-ones(1,nx); + [A,B,C,D]=abcd(Sys); // + J=flag; + // F=A+J*C;G=[B+J*D,-J]; // + Obs=syslin(td,A+J*C,[B+J*D,-J],eye(A));U=[];m=[];return; //Ao + end + if RHS==3 then + if size(alfa,"*")==1 then alfa=alfa*ones(1,nx);end + end + select flag + case "pp" + m=m2; + no=nx-m; + alfa=alfa(1:no); + [A,B,C,D]=abcd(sl2); + Ao=A(m+1:nx,m+1:nx); + Bo=B(m+1:nx,:); + Co=C(:,m+1:nx); + Do=D; + J=-ppol(Ao',Co',alfa);J=J'; + F=Ao+J*Co;G=[Bo+J*Do,-J]; + Obs=syslin(td,F,G,eye(Ao)); + return; + case "st" + m=m1; + no=nx-m; + alfa=alfa(1:no); + [A,B,C,D]=abcd(sl2); + Ao=A(m+1:nx,m+1:nx); + Bo=B(m+1:nx,:); + Co=C(:,m+1:nx); + Do=D; + J=stabil(Ao',Co',alfa);J=J'; + F=Ao+J*Co;G=[Bo+J*Do,-J]; + Obs=syslin(td,F,G,eye(Ao)); + return; + end +endfunction diff --git a/modules/cacsd/macros/obsv_mat.bin b/modules/cacsd/macros/obsv_mat.bin Binary files differnew file mode 100755 index 000000000..787051369 --- /dev/null +++ b/modules/cacsd/macros/obsv_mat.bin diff --git a/modules/cacsd/macros/obsv_mat.sci b/modules/cacsd/macros/obsv_mat.sci new file mode 100755 index 000000000..4eba98711 --- /dev/null +++ b/modules/cacsd/macros/obsv_mat.sci @@ -0,0 +1,32 @@ +// 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 o=obsv_mat(a,c) + + [lhs,rhs]=argn(0) + select typeof(a) + case "constant" then + if rhs==1 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected"),"obsv_mat",2)), + end + [m,n]=size(a) + if m<>n then error(20,1),end + [mb,nb]=size(c);if nb<>n then error(60),end + case "state-space" then + [a,c]=a([2,4]) + [n,n]=size(a) + else + if rhs==1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear dynamical system expected.\n"),"obsv_mat",1)) + else + error(msprintf(gettext("%s: Wrong type of input argument #%d: Array of floating point numbers expected.\n"),"obsv_mat",1)) + end + end; + o=c;for k=1:n-1, o=[c;o*a],end +endfunction diff --git a/modules/cacsd/macros/obsvss.bin b/modules/cacsd/macros/obsvss.bin Binary files differnew file mode 100755 index 000000000..41553d507 --- /dev/null +++ b/modules/cacsd/macros/obsvss.bin diff --git a/modules/cacsd/macros/obsvss.sci b/modules/cacsd/macros/obsvss.sci new file mode 100755 index 000000000..3ab4ecc60 --- /dev/null +++ b/modules/cacsd/macros/obsvss.sci @@ -0,0 +1,50 @@ +// 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 [a,b,c]=obsvss(a,b,c,tol) + + [lhs,rhs]=argn(0) + select typeof(a) + case "constant" then + if lhs<>3 then + error(msprintf(gettext("%s: Wrong number of output arguments: %d expected.\n"),"obsvss",3)), + end + select rhs + case 3 then + tol = 100*%eps + case 4 then , + else + error(msprintf(gettext("%s: Wrong number of input arguments: %d or %d expected.\n"),"obsvss",3,4)) + end; + case "state-space" then + if lhs<>1 then + error(msprintf(gettext("%s: Wrong number of output arguments: %d expected.\n"),"obsvss",1)), + end + select rhs + case 1 then + tol=100*%eps + case 2 then + tol=b + else + error(msprintf(gettext("%s: Wrong number of input arguments: %d or %d expected.\n"),"obsvss",1,2)) + end; + [a,b,c,d,x0,dom]=a(2:7) + else + if rhs==1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"obsvss",1)) + else + error(msprintf(gettext("%s: Wrong type of input argument #%d: Array of floating point numbers expected.\n"),"obsvss",1)) + end + end; + // + [no,u]=contr(a',c',tol) + u=u(:,1:no) + a=u'*a*u;b=u'*b;c=c*u + if lhs==1 then a=syslin(dom,a,b,c,d,u'*x0),end +endfunction diff --git a/modules/cacsd/macros/p_margin.bin b/modules/cacsd/macros/p_margin.bin Binary files differnew file mode 100755 index 000000000..f451da9c3 --- /dev/null +++ b/modules/cacsd/macros/p_margin.bin diff --git a/modules/cacsd/macros/p_margin.sci b/modules/cacsd/macros/p_margin.sci new file mode 100755 index 000000000..a8c10fd9c --- /dev/null +++ b/modules/cacsd/macros/p_margin.sci @@ -0,0 +1,72 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010-2011 - INRIA - Serge Steer +// +// 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 [phm,fr]=p_margin(h) + //compute the phase margin of a SISO transfer function + select typeof(h) + case "rational" then + case "state-space" then + h=ss2tf(h); + else + error(97,1) + end + if or(size(h)<>[1 1]) then + error(msprintf(_("%s: Wrong size for input argument #%d: Single input, single output system expected.\n"),"p_margin",1)) + end + eps=1.e-7;// threshold used for testing if complex numbers are real or pure imaginary + + if h.dt=="c" then //continuous time case + w=poly(0,"w"); + niw=horner(h.num,%i*w); + diw=horner(h.den,%i*w); + // |n(iw)/d(iw)|=1 <-- (n(iw)*n(-iw))/(d(iw)*d(-iw))=1 <-- (n(iw)*n(-iw)) - (d(iw)*d(-iw))=0 + w=roots(real(niw*conj(niw)-diw*conj(diw)),"e"); + //select positive real roots + ws=real(w(find((abs(imag(w))<eps)&(real(w)>0)))); //frequency points with unitary modulus + if ws==[] then + phm=[]; + fr=[]; + return + end + f=horner(h,%i*ws); + else //discrete time case + if h.dt=="d" then + dt=1; + else + dt=h.dt; + end + // |h(e^(i*w*dt))|=1 <-- h(e^(i*w*dt))*h(e^(-i*w*dt)) + z=poly(0,varn(h.den)); + sm=simp_mode(); + simp_mode(%f); + hh=h*horner(h,1/z)-1; + simp_mode(sm); + //find the numerator roots + z=roots(hh.num,"e"); + z(abs(abs(z)-1)>eps)=[];// retain only roots with modulus equal to 1 + w=log(z)/(%i*dt); + ws=real(w(abs(imag(w))<eps&real(w)>0)); //frequency points with unitary modulus + if ws==[] then + phm=%inf; + fr=[]; + return + end + f=horner(h,exp(%i*ws*dt)); + end + phi=atand(imag(f),real(f));// phase of the frequency response (in [-180 180]) + + //avoid near 0 negative phases that will give phm=180 instead of -180 + phi(phi>-1e-12&phi<0)=0; + //compute the margins + phm=pmodulo(phi,360)-180; + //select the min value together with associated frequency in Hz + [w,k]=min(abs(phm)); + phm=phm(k) + fr=ws(k)/(2*%pi); +endfunction diff --git a/modules/cacsd/macros/parrot.bin b/modules/cacsd/macros/parrot.bin Binary files differnew file mode 100755 index 000000000..09c21ed2e --- /dev/null +++ b/modules/cacsd/macros/parrot.bin diff --git a/modules/cacsd/macros/parrot.sci b/modules/cacsd/macros/parrot.sci new file mode 100755 index 000000000..b0fbbaa43 --- /dev/null +++ b/modules/cacsd/macros/parrot.sci @@ -0,0 +1,32 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque +// +// 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 [Kopt,gamaopt]=parrot(D,r) + //Given a matrix D partionned as [D11 D12 + // D21 D22] + //where size(D22)=r=[r1,r2] + //compute a matrix K such that + //largest singular value of [D11 D12 + // D21 D22+K] + //is minimal (Parrot's theorem) + //! + + [l,k]=size(D); + l1=1:(l-r(1)); + l2=(l-r(1)+1):l; + k1=1:(k-r(2)) + k2=(k-r(2)+1):k; + D11=D(l1,k1); + D12=D(l1,k2); + D21=D(l2,k1); + D22=D(l2,k2); + D1=[D11,D12];D2=[D11;D21]; + gamaopt=max( max(svd(D1)),max(svd(D2)) ); + Kopt=-D22-D21*inv(gamaopt*gamaopt*eye()-D11'*D11)*D11'*D12; +endfunction diff --git a/modules/cacsd/macros/pfss.bin b/modules/cacsd/macros/pfss.bin Binary files differnew file mode 100755 index 000000000..026f775fe --- /dev/null +++ b/modules/cacsd/macros/pfss.bin diff --git a/modules/cacsd/macros/pfss.sci b/modules/cacsd/macros/pfss.sci new file mode 100755 index 000000000..115a20565 --- /dev/null +++ b/modules/cacsd/macros/pfss.sci @@ -0,0 +1,112 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA +// Copyright (C) - 2014 - Samuel GOUGEON <sgougeon@free.fr> +// +// 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 elts = pfss(S, rmax, cord) + //Syntax : elts = pfss(S) + //Partial fraction decomposition of the linear system S (in state-space form): + // elts is the list of linear systems which add up to S + // i.e. elts = list(S1, S2, S3, ..., Sn) with S1 + S2 +... +Sn = S + // Each Si contains some poles of S according to the block-diagonalization + // of the A matrix of S. + // If S is given in transfer form, it is first converted into state-space + // and each subsystem is then converted in transfer form. + + select argn(2) + case 1 then + rmax = []; + cord = []; + case 2 then + if type(rmax) == 10 then + cord = rmax; + rmax=[]; + elseif type(rmax) == 1 then + cord = []; + end + end + + if and(typeof(S) <> ["rational", "state-space"]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"), "pfss", 1)) + end + if typeof(S) == "rational" then + flag = varn(S("num")) + S = tf2ss(S) + else + flag = "" + end + + [f, g, h, dd, dom] = S([2:5, 7]); + [n, n] = size(f); + if rmax == [] then + [f, x, bs] = bdiag(f,max(100,norm(f,1))); + else + [f, x, bs] = bdiag(f, rmax); + end + h = h*x; g = x\g; + k = 1; ll = 0; + elts = list(); + for l = bs', + ind = k:k+l-1; + f1l = f(ind, ind); + gl = g(ind, :); + hl = h(:, ind); + elts(ll+1) = syslin("c", f1l, gl, hl) + ll = ll+1; k = k+l; + end; + if argn(2) == 2 then + select cord + case "c" + nb = size(bs, "*"); + class = []; + for k = 1:nb + oneortwo = bs(k); ss = elts(k); A = ss(2); + if oneortwo == 1 then + class = [class, real(spec(A))]; + end + if oneortwo > 1 then + class = [class, min(real(spec(A)))]; + end + end; + [cl, indi] = gsort(-class); + elts1 = elts; + for k = 1:size(elts); + elts(k) = elts1(indi(k)); + end + case "d" + nb = size(bs, "*"); + class = []; + for k = 1:nb + oneortwo = bs(k); ss = elts(k); A = ss(2); + if oneortwo == 1 then + class = [class, abs(spec(A))]; + end + if oneortwo > 1 then + class = [class, max(abs(spec(A)))]; + end + end; + [cl, indi] = gsort(-class); + elts1 = elts; + for k = 1:size(elts); + elts(k) = elts1(indi(k)); + end + end + end + if type(dd) == 1 then + if norm(dd, "fro") <> 0 then elts(ll+1) = dd, end + end + if type(dd) == 2 then + if norm(coeff(dd), 1) > %eps then elts(ll+1) = dd, end + end + if flag ~= "" then + k = size(elts) + for kk = 1:k + elts(kk) = varn(ss2tf(elts(kk)), flag) + end + end +endfunction diff --git a/modules/cacsd/macros/phasemag.bin b/modules/cacsd/macros/phasemag.bin Binary files differnew file mode 100755 index 000000000..14cc63ba5 --- /dev/null +++ b/modules/cacsd/macros/phasemag.bin diff --git a/modules/cacsd/macros/phasemag.sci b/modules/cacsd/macros/phasemag.sci new file mode 100755 index 000000000..c0c7c22ff --- /dev/null +++ b/modules/cacsd/macros/phasemag.sci @@ -0,0 +1,41 @@ +// 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 [phi,db]=phasemag(z,mod) + // + + mod_def="c" //continuous representation + //mod_def='m' //representation modulo 360 degrees + [lhs,rhs]=argn(0) + if lhs==2 then + db=20*log(abs(z))/log(10), + end + if rhs<>2 then + mod=mod_def + end + //compute first phase value in (-pi, pi] + phi1=atan(imag(z(:,1)),real(z(:,1))) + //compute phase increments in (-pi, pi] + ind = find(z==0); + if ind <> [] then + z(ind) = 1; // To avoid division by 0 (0 and 1 have the same phase) + end + z2=z(:,2:$)./z(:,1:$-1) + dphi=atan(imag(z2),real(z2)) + phi=cumsum([phi1 dphi],2) + + if part(mod,1)<>"c" then // reset modulo 360 + phi=modulo(phi,2*%pi) + end + phi=phi*180/%pi //transform in degree + + if typeof(z) == "hypermat" then + phi = matrix(phi, size(z)); + end +endfunction diff --git a/modules/cacsd/macros/phaseplot.bin b/modules/cacsd/macros/phaseplot.bin Binary files differnew file mode 100755 index 000000000..75522d4b7 --- /dev/null +++ b/modules/cacsd/macros/phaseplot.bin diff --git a/modules/cacsd/macros/phaseplot.sci b/modules/cacsd/macros/phaseplot.sci new file mode 100755 index 000000000..c23c83128 --- /dev/null +++ b/modules/cacsd/macros/phaseplot.sci @@ -0,0 +1,107 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2011 - INRIA - Serge Steer +// 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 []=phaseplot(varargin) + rhs=size(varargin) + if type(varargin($))==10 then + comments=varargin($); + rhs=rhs-1; + else + comments=[]; + end + fname="phaseplot";//for error messages + + fmax=[]; + if or(typeof(varargin(1))==["state-space" "rational"]) then + //sys,fmin,fmax [,pas] or sys,frq + refdim=1 //for error message + if rhs==1 then + [frq,repf]=repfreq(varargin(1),1d-3,1d3); + elseif rhs==2 then //sys,frq + if size(varargin(2),2)<2 then + error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"),.. + fname,2,1)); + end + [frq,repf]=repfreq(varargin(1:rhs)); + elseif or(rhs==(3:4)) then //sys,fmin,fmax [,pas] + [frq,repf]=repfreq(varargin(1:rhs)); + else + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),fname,1,5)) + end + [phi,d]=phasemag(repf); + elseif type(varargin(1))==1 then + //frq,db,phi [,comments] or frq, repf [,comments] + refdim=2 + select rhs + case 2 then //frq,repf + frq=varargin(1); + if size(frq,2)<2 then + error(msprintf(_("%s: Wrong size for input argument #%d: A row vector with length>%d expected.\n"),.. + fname,1,1)) + end + if size(frq,2)<>size(varargin(2),2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),.. + fname,1,2)) + end + + [phi,d]=phasemag(varargin(2)) + case 3 then //frq,db,phi + [frq,d,phi]=varargin(1:rhs) + if size(frq,2)<>size(d,2) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),.. + fname,1,2)) + end + else + error(msprintf(_("%s: Wrong number of input arguments: %d to %d expected.\n"),fname,2,4)) + end + else + error(msprintf(_("%s: Wrong type for input argument #%d: Linear dynamical system or row vector of floats expected.\n"),fname,1)) + end; + + frq=frq'; + phi=phi'; + [n,mn]=size(phi); + if and(size(comments,"*")<>[0 mn]) then + error(msprintf(_("%s: Incompatible input arguments #%d and #%d: Same number of elements expected.\n"),... + fname,refdim,rhs+1)) + end + + // + fig=gcf(); + id=fig.immediate_drawing; + fig.immediate_drawing="off"; + + axes = gca() ; + if size(axes.children,"*")==0 then + axes.data_bounds=[min(frq),min(phi);max(frq),max(phi)] + axes.x_label.text=_("Frequency (Hz)") + axes.y_label.text=_("Phase (Deg)") + + else + axes.data_bounds=[min([min(frq),min(phi)],axes.data_bounds(1,:)); + max([max(frq),max(phi)],axes.data_bounds(2,:))]; + end + axes.axes_visible="on"; + axes.log_flags = "lnn" ; + axes.grid=color("lightgrey")*ones(1,3); + + if size(phi,2)>1&size(frq,2)==1 then + xpolys(frq(:,ones(1,mn)),phi,1:mn) + e=gce(); + else + xpolys(frq,phi,1:mn) + e=gce(); + end + for i=1:size(e.children,"*") + e.children(i).display_function = "formatPhaseplotTip"; + end + if comments<>[] then + legend(comments) + end + fig.immediate_drawing=id; +endfunction diff --git a/modules/cacsd/macros/plzr.bin b/modules/cacsd/macros/plzr.bin Binary files differnew file mode 100755 index 000000000..7bfbb89f7 --- /dev/null +++ b/modules/cacsd/macros/plzr.bin diff --git a/modules/cacsd/macros/plzr.sci b/modules/cacsd/macros/plzr.sci new file mode 100755 index 000000000..9bbbc0d7f --- /dev/null +++ b/modules/cacsd/macros/plzr.sci @@ -0,0 +1,129 @@ +// 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 plzr(a,b,c,d) + // + // Copyright INRIA + [lhs,rhs]=argn(0) + + if rhs == 0 then + s=poly(0,"s"); + n=[1+s, 2+3*s+4*s^2, 5;0, 1-s, s]; + d=[1+3*s, 5-s^3, s+1;1+s, 1+s+s^2, 3*s-1]; + h=syslin("c",n./d); + plzr(h); + return; + end + + select typeof(a) + case "rational" then + if rhs<>1 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected.\n"),"plzr",1)), + end + a=tf2ss(a), + dt=a.dt; + [a,b,c,d]=a(2:5) + if type(d)<>1 then + error(msprintf(gettext("%s: Wrong value of input argument #%d: Proper system expected.\n"),"plzr",1)); + end + case "state-space" then + if rhs<>1 then + error(msprintf(gettext("%s: Wrong number of input arguments: %d expected.\n"),"plzr",1)), + end + dt=a(7); + [a,b,c,d]=a(2:5) + if type(d)<>1 then + error(msprintf(gettext("%s: Wrong value of input argument #%d: Proper system expected.\n"),"plzr",1)); + end + case "constant" then + if rhs<>4 then + error(msprintf(gettext("%s: Wrong number of input argument: %d expected.\n"),"plzr",4)), + end + if type(d)<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Array of floating point numbers expected.\n"),.. + "plzr",4)); + end + dt=[]; + else + if rhs==1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear dynamical system expected.\n"),"plzr",1)) + else + error(msprintf(gettext("%s: Wrong type of input argument #%d: Array of floating point numbers expected.\n"),"plzr",1)) + end + end + if type(d)<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Array of floating point numbers expected.\n"),.. + "plzr",4)); + end + + dr=spec(a) + [al,be]=tr_zer(a,b,c,d) + nr=al./be + ni=imag(nr);nr=real(nr) + di=imag(dr);dr=real(dr) + // + mxx=max([nr;dr;1]*1.1) + mnx=min([nr;dr;-1]*1.1) + my=max(abs([ni;di;1])*1.1) + + rect=[mnx, -my, mxx, my]; + + wdim=get(gcf(),"axes_size") + dx=(mxx-mnx)/wdim(1);dy=2*my/wdim(2) + if dy>dx then + ax=(dy*wdim(1)-mxx+mnx)/2 + mxx=mxx+ax;mnx=mnx-ax + elseif dy<dx then + ay=(dx*wdim(2)-2*my)/2 + my=my+ay + end + rect=[mnx, -my, mxx, my]; + + fig=gcf(); + immediate_drawing=fig.immediate_drawing; + fig.immediate_drawing="off"; + + ax=gca(); + ax.data_bounds=[mnx, -my; mxx, my]; + ax.axes_visible="on"; + + legs=[],lhandle=[] + if size(nr,"*")<>0 then + xpoly(nr,ni) + e=gce();e.line_mode="off";e.mark_mode="on"; + e.mark_size_unit="point";e.mark_size=7;e.mark_style=5; + legs=gettext("Zeros") + lhandle=[e;lhandle] + end; + if size(dr,"*")<>0 then + xpoly(dr,di) + e=gce();e.line_mode="off";e.mark_mode="on"; + e.mark_size_unit="point";e.mark_size=7;e.mark_style=2; + legs=[gettext("Poles");legs] + lhandle=[e;lhandle] + end + if dt == "d" then + ax.grid=ones(1,3)*color("gray") + ax.box = "on"; + xarc(-1,1,2,2,0,360*64) + xtitle(gettext("Transmission zeros and poles"),gettext("Real axis"), ... + gettext("Imaginary axis")); + else + ax.grid=ones(1,3)*color("gray") + ax.box = "on"; + ymin=ax.data_bounds(1,2); + ymax=ax.data_bounds(2,2); + xsegs([0,0],[ymin,ymax]) + xtitle(gettext("Transmission zeros and poles"),gettext("Real axis"), ... + gettext("Imaginary axis")); + end + + if legs<>[] then legend(lhandle,legs,1),end + fig.immediate_drawing=immediate_drawing; + show_window(); +endfunction diff --git a/modules/cacsd/macros/prbs_a.bin b/modules/cacsd/macros/prbs_a.bin Binary files differnew file mode 100755 index 000000000..402d9a83a --- /dev/null +++ b/modules/cacsd/macros/prbs_a.bin diff --git a/modules/cacsd/macros/prbs_a.sci b/modules/cacsd/macros/prbs_a.sci new file mode 100755 index 000000000..141e52f59 --- /dev/null +++ b/modules/cacsd/macros/prbs_a.sci @@ -0,0 +1,34 @@ +// 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 [u]=prbs_a(n,nc,ids) + //generation of pseudo random binary sequences + //u=[u0,u1,...,u_(n-1)]; + //u takes values in {-1,1} and changes at most nc times its sign. + //ids can be used to fix the date at which u must change its sign + //ids is then an integer vector with values in [1:n]. + //! + [lhs,rhs]=argn(0) + if rhs <=2, + rand("uniform"); + yy= int(min(max(n*rand(1,nc),1*ones(1,nc)),n*ones(1,nc))); + ids=gsort(yy);ids=[n,ids,1]; + else + [n1,n2]=size(ids); + ids=[n,min(n*ones(ids),max(gsort(ids),1*ones(ids))),1]; + end + u=0*ones(1,n); + [n1,n2]=size(ids); + val=1; + for i=1:n2-1, + if ids(i)<>ids(i+1); + u(ids(i+1):ids(i))=val*ones(ids(i+1):ids(i));val=-1*val; + end + end +endfunction diff --git a/modules/cacsd/macros/projsl.bin b/modules/cacsd/macros/projsl.bin Binary files differnew file mode 100755 index 000000000..8f700433a --- /dev/null +++ b/modules/cacsd/macros/projsl.bin diff --git a/modules/cacsd/macros/projsl.sci b/modules/cacsd/macros/projsl.sci new file mode 100755 index 000000000..77aa6a15e --- /dev/null +++ b/modules/cacsd/macros/projsl.sci @@ -0,0 +1,16 @@ +// 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 [slp]=projsl(sl,q,m) + //slp= projected model of sl q*m is the full rank + //factorization of the projection. + //! + + slp=syslin(sl(7),m*sl(2)*q,m*sl(3),sl(4)*q,sl(5),m*sl(6)) +endfunction diff --git a/modules/cacsd/macros/repfreq.bin b/modules/cacsd/macros/repfreq.bin Binary files differnew file mode 100755 index 000000000..2dbe8bec2 --- /dev/null +++ b/modules/cacsd/macros/repfreq.bin diff --git a/modules/cacsd/macros/repfreq.sci b/modules/cacsd/macros/repfreq.sci new file mode 100755 index 000000000..c3d844446 --- /dev/null +++ b/modules/cacsd/macros/repfreq.sci @@ -0,0 +1,110 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 1984-2011 - INRIA - Serge STEER +// +// 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 [frq,rep,splitf]=repfreq(sys,fmin,fmax,pas) + + pas_def="auto"; + l10=log(10); + [lhs,rhs]=argn(0) + //discretization + if and(typeof(sys)<>[ "rational" "state-space" ]) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear dynamical system expected.\n"),"repfreq",1)) + end + dom=sys.dt + if dom==[]|dom==0 then error(96,1),end + if dom=="d" then dom=1;end + + select rhs + case 1 then + pas=pas_def + if dom=="c" then fmax=1.d3; else fmax=1/(2*dom),end + fmin=0 + case 2 then + if type(fmin)==10 then + rhs=1 + pas=pas_def + if dom=="c" then fmax=1.d3; else fmax=1/(2*dom),end + if fmin=="sym" then + fmin=-fmax + else + fmin=0 + end + else + frq=fmin + end + case 3 then + pas=pas_def + case 4 then , + else + error(msprintf(gettext("%s: Wrong number of input arguments: %d to %d expected.\n"), "repfreq",1,4)) + end; + splitf=1 + if rhs<>2 then + if fmin==[] then + fmin=0, + end + if fmax==[]|fmax==%inf then + if dom=="c" then + fmax=1.d3; + else + fmax=1/(2*dom); + end + end + + if type(pas)==1 then + splitf=1 + eps=1.e-14 + if fmin<0&fmax>=0 then + frq=- [exp(l10*((log(eps)/l10):pas:(log(-fmin)/l10))) -fmin]; + if fmax>eps then + frq1=[exp(l10*((log(eps)/l10):pas:(log(fmax)/l10))) fmax]; + frq=[frq($:-1:1) frq1] + else + frq=frq($:-1:1); + end + elseif fmin<0&fmax<0 then + frq= [exp(l10*((log(-fmax)/l10):pas:(log(-fmin)/l10))) -fmin]; + frq=-frq($:-1:1); + elseif fmin >= fmax then + error(msprintf(gettext("%s: Wrong value for input arguments #%d and #%d: %s < %s expected.\n"),.. + "repfreq",2,3,"fmin","fmax")); + else + fmin=max(eps,fmin); + frq=[exp(l10*((log(fmin)/l10):pas:(log(fmax)/l10))) fmax]; + end + else + [frq,bnds,splitf]=calfrq(sys,fmin,fmax) + end; + end + // + typ=sys(1) + select typ(1) + case "r" then + [n,d]=sys(["num","den"]), + [mn,nn]=size(n) + if nn<>1 then error(95,1),end + if dom=="c" then + rep=freq(n,d,2*%pi*%i*frq), + else + rep=freq(n,d,exp(2*%pi*%i*dom*frq)), + end; + case "lss" then + [a,b,c,d,x0]=sys(2:6), + [mn,nn]=size(b) + if nn<>1 then error(95,1),end + if dom=="c" then + rep=freq(a,b,c,d,2*%pi*%i*frq) + else + rep=freq(a,b,c,d,exp(2*%pi*%i*dom*frq)) + end; + else error(97,1), + end; + //representation + if lhs==1 then frq=rep,end +endfunction diff --git a/modules/cacsd/macros/ric_desc.bin b/modules/cacsd/macros/ric_desc.bin Binary files differnew file mode 100755 index 000000000..9238309e8 --- /dev/null +++ b/modules/cacsd/macros/ric_desc.bin diff --git a/modules/cacsd/macros/ric_desc.sci b/modules/cacsd/macros/ric_desc.sci new file mode 100755 index 000000000..0d182dcd6 --- /dev/null +++ b/modules/cacsd/macros/ric_desc.sci @@ -0,0 +1,78 @@ +// 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 [X1,X2,zero]=ric_desc(H,E) + //[X1,X2,zero]=ric_desc(H [,E]) Descriptor Riccati solver with + // hamiltonian matrices as inputs. + // (see also riccati) + //In the continuous time case calling sequence is ric_desc(H) (one input). + // Riccati equation is: + // (Ec) A'*X + X*A + X*R*X -Q = 0. + // Defining the hamiltonian matrix H by: + // H = [A R; + // Q -A'] + // with [X1,X2,err]=ric_desc(H),solution X is given by X=X1/X2. + // zero=norm 1 of lhs of (Ec) + // + // (solution X is also given by X=riccati(A,Q,R,'c')) + // + // + //In the discrete-time case calling sequence is ric_desc(H,E) (two inputs). + // Riccati solution is: + // (Ed) A'*X*A-(A'*X*B*(R+B'*X*B)^-1)*(B'*X*A)+C-X = 0. + // + // Defining G=B/R*B' and the hamiltonian pencil (E,H) by: + // E=[eye(n,n),G; + // 0*ones(n,n),A'] + // + // H=[A, 0*ones(n,n); + // -C, eye(n,n)]; + // with [X1,X2,err]=ric_desc(H,E),solution X is given by X=X1/X2. + // zero=norm 1 of lhs of (Ed) + // + // (solution X is also given by X=riccati(A,G,C,'d') with G=B/R*B') + //! + + [LHS,RHS]=argn(0); + if RHS==1 then + [n2,n2]=size(H); + n1=n2/2; + A=H(1:n1,1:n1); + //R=H(1:n1,n1+1:n2); Q=H(n1+1:n2,1:n1); + [Hb,W1]=bdiag(H); + if cond(W1) > 1.d10*norm(H,1) then + // write(%io(2),'Warning : Bad conditioning => balancing'); + [Hb,W1]=balanc(H); + end + if cond(W1) > 1.d+10*norm(H,1) then Hb=H,W1=eye(W1);end + + [W2,n]=schur(Hb,"c");Hb=[] + if n<>n1 then mprintf(gettext("%s: Stationary Riccati solver failed.\n"),"ric_desc");end + W1=W1*W2;W2=[] + UV=W1(:,1:n1);W1=[] + X2=UV(1:n1,:);X1=UV(n1+1:n2,:);UV=[]; + if n<>n1 then + X2=eye(n1,n1);X1=0; + end + zr=X2'*A'*X1+X1'*A*X2+X1'*H(1:n1,n1+1:n2)*X1-X2'*H(n1+1:n2,1:n1)*X2; + zero=norm(zr,1); + end + if LHS==1 then X1=X1/X2;end + if RHS==2 then + [n2,n2]=size(H);n1=n2/2; + n1=n2/2; + [UV,n]=schur(H,E,"d"); + X2=UV(1:n,1:n);X1=UV(n+1:2*n,1:n); + if LHS==3 then + A=H(1:n1,1:n1);G=E(1:n,n+1:2*n);C=-H(n+1:2*n,1:n);B=real(sqrtm(G));R=eye(A); + X=X1/X2;zero=A'*X*A-(A'*X*B/(R+B'*X*B))*(B'*X*A)+C-X; + end + end + if LHS==1 then X=X1/X2;end +endfunction diff --git a/modules/cacsd/macros/riccati.bin b/modules/cacsd/macros/riccati.bin Binary files differnew file mode 100755 index 000000000..99a709ce0 --- /dev/null +++ b/modules/cacsd/macros/riccati.bin diff --git a/modules/cacsd/macros/riccati.sci b/modules/cacsd/macros/riccati.sci new file mode 100755 index 000000000..89ce0ecb8 --- /dev/null +++ b/modules/cacsd/macros/riccati.sci @@ -0,0 +1,56 @@ +// 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 [x1,x2]=riccati(a,b,c,dom,typ) + //[x1,[x2]]=riccati(a,b,c,dom,[typ]) is a Riccati solver + // x=x1/x2 solves: + // a'*x+x*a-x*b*x+c=0 (continuous time case) + // a'*x*a-(a'*x*b1/(b2+b1'*x*b1))*(b1'*x*a)+c-x with b=b1/b2*b1' + // (discrete time case) + // If called with LHS=1 (one output argument) riccati returns x. + // + // -- a,b,c real matrices nxn, b and c symmetric. + // -- dom = 'c' or 'd' for the time domain (continuous or discrete) + // -- typ = 'eigen' --->block diagonalization + // typ = 'schur' --->schur method + // See also ric_desc + //! + + [lhs,rhs]=argn(0), + if rhs==4 then typ="eigen",end, + ham=[a -b;-c -a'], + [n,n]=size(a), + if part(dom,1)=="c" then + select typ, + case "schur" then + [s,d]=schur(ham,"c"), + if d<>n then + error(msprintf(gettext("%s: Wrong dimension (%d) of stable subspace: %d expected.\n"),"riccati",d, n)) + end + s=s(:,1:n), + case "eigen" then + [hb,u1]=bdiag(ham), + [u2,d]=schur(hb,"c"), + u=u1*u2, + if d<>n then + error(msprintf(gettext("%s: Wrong dimension (%d) of stable subspace: %d expected.\n"),"riccati",d, n)) + end + s=u(:,1:n), + end, + else + aa=[eye(n,n) b;0*ones(n,n) a'],bb=[a 0*ones(n,n);-c eye(n,n)], + [bs,as,s,n1]=schur(bb,aa,"d"); + if n1<>n then + error(msprintf(gettext("%s: Wrong dimension (%d) of stable subspace: %d expected.\n"),"riccati",n1, n)) + end + s=s(:,1:n1); + end, + x1=s(n+1:2*n,:),x2=s(1:n,:), + if lhs==1 then x1=x1/x2,end +endfunction diff --git a/modules/cacsd/macros/routh_t.bin b/modules/cacsd/macros/routh_t.bin Binary files differnew file mode 100755 index 000000000..f11067ab5 --- /dev/null +++ b/modules/cacsd/macros/routh_t.bin diff --git a/modules/cacsd/macros/routh_t.sci b/modules/cacsd/macros/routh_t.sci new file mode 100755 index 000000000..4e39c925f --- /dev/null +++ b/modules/cacsd/macros/routh_t.sci @@ -0,0 +1,136 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - Serge STEER +// Copyright (C) 1999 - Lucien.Povy@eudil.fr (to get a good table) +// Copyright (C) 2013 - Charlotte HECQUET (new option) +// Copyright (C) 2013 - A. Khorshidi (to define a new optional output argument) +// +// 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 par of this distribution. The terms +// are also available at +// http://www.cecill.info/licences/Licence_CeCILL_V2.1-en.txt + +function [r,num]=routh_t(h,k,normalized) + //r=routh_t(h,k) computes routh table of denominator of the + //system described by transfer matrix SISO continue h with the + //feedback by the gain k + //If k=poly(0,'k') we will have a polynomial matrix with dummy variable + //k, formal expression of the Routh table. + //r=routh_t(d) computes Routh table of h :attention ! d=denom of system + + //If a zero row appears, it means that there exist a pair of pure imaginary + //roots (oscillating system) or symmetric real roots. In this case, the pure imaginary roots are the + //imaginary roots of the bisquare polynomial given by the previous row. The + //routh table can be continued replacing this row by the derivative of this + //polynomial. + //see http://www.jdotec.net/s3i/TD_Info/Routh/Routh.pdf for degenerated + //cases + + //see also + //Comments on the Routh-Hurwitz criterion, Shamash, Y.,Automatic Control, IEEE T.A.C + //Volume 25, Issue 1, Feb 1980 Page(s): 132 - 133 + + //http://controls.engin.umich.edu/wiki/index.php/RouthStability + [lhs,rhs]=argn(0); + h1=h(1); + flag=1; + if rhs==3 then + if normalized==%t then + flag=1; + else + flag=0; + end + rhs=2; + end + if rhs==2 then + if typeof(h)<>"rational" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: rational fraction array expected.\n"),"routh_t",1)); + end + [n,d]=h(2:3) + if size(n,"*")<>1 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Single input, single output system expected.\n"),"routh_t",1)) + end + nd=max([degree(d) degree(n)])+1; + cod=coeff(d,0:nd-1);//coeff du denominateur + con=coeff(n,0:nd-1);//coeff du numerateur + cobf=cod+k*con //coeff de la boucle fermee + else + if type(h)>2 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Polynomial array expected.\n"),"routh_t",1)); + end + if size(h,"*")<>1 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A polynomial expected.\n"),"routh_t",1)) + end + + nd=degree(h)+1; + cobf=coeff(h,0:nd-1) + end; + // + r1=cobf(nd:-2:1); + r2=cobf(nd-1:-2:1); + ncol=size(r1,"*"); + if size(r2,"*")<>ncol then r2=[r2,0],end + r=[r1;r2] + if ncol<2 then r=[],return,end; + if rhs==2 then + + for i=3:nd, + if flag==0 then // for a non-normalized table + r(i,1:ncol-1)=[r(i-1,1),-r(i-2,1)]*[r(i-2,2:ncol);r(i-1,2:ncol)] + else // for a normalized table + if r(i-1,1)==0 then + if type(k)<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar expected.\n"),"routh_t",2)); + end + r(i-1,1)=poly(0,"eps") + end + r(i,1:ncol-1)=[1.,-r(i-2,1)/r(i-1,1)]*[r(i-2,2:ncol);r(i-1,2:ncol)] + end + end; + else + for i=3:nd, + // Special Case: Row of zeros detected: + if and(r(i-1,:)==0) then + naux=nd-i+2 //order of previous polynomial + exponents=naux:-2:0 + ncoeff=size(exponents,"*") + r(i-1,1:ncoeff)=r(i-2,1:ncoeff).*exponents //derivative of previous polynomial + end + // Special Case: First element of the 2nd row or upper is zero and is replaced with %eps: + if r(i-1,1)==0 then + if rhs==1 then + if typeof(r)=="rational" then + //scilab is not able to handle multivariable polynomials + r=horner(r,%eps^2); + end + r(i-1,1)=poly(0,"eps") + else + r(i-1,1)=%eps^2, + end + end + r(i,1:ncol-1)=[1.,-r(i-2,1)/r(i-1,1)]*[r(i-2,2:ncol);r(i-1,2:ncol)] + + end; + end; + + if lhs==2 then + if rhs==2 & type(k)<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A scalar expected.\n"),"routh_t",2)); + end + nrow=size(r,"r") + num = 0; + c = 0; + for i = 1:nrow + if horner(r(i,1),%eps) >= 0 then + if c == 1 then + num= num+1; + c = 0; + end + elseif c == 0 then + num= num+1; + c = 1; + end; + end; + end + +endfunction diff --git a/modules/cacsd/macros/rowinout.bin b/modules/cacsd/macros/rowinout.bin Binary files differnew file mode 100755 index 000000000..c014f0dbb --- /dev/null +++ b/modules/cacsd/macros/rowinout.bin diff --git a/modules/cacsd/macros/rowinout.sci b/modules/cacsd/macros/rowinout.sci new file mode 100755 index 000000000..01ee7531f --- /dev/null +++ b/modules/cacsd/macros/rowinout.sci @@ -0,0 +1,51 @@ +// 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 [Inn,X,Gbar]=rowinout(G) + // Inner-outer factorization (and row compression) of (lxp) G =:[A,B,C,D] with l>=p + // G is assumed to be tall (l>=p) without zero on the imaginary axis + // and with a D matrix which is full column rank. G must also be stable for + // having Gbar stable. + // + // G admits the following inner-outer factorization: + // + // G = [ Inn ] | Gbar | + // | 0 | + // + // where Inn is square and inner (all pass and stable) and Gbar square and outer i.e: + // Gbar is square bi-proper and bi-stable (Gbar inverse is also proper and stable); + // + // Note that: + // [ Gbar ] + // X*G = [ - ] + // [ 0 ] + // is a row compression of G where X = Inn inverse is all-pass: + // T + // X is lxl and X (-s) X(s) = Identity (all-pass property). + // + + G1=G(1); + flag="ss";if G1(1)=="r" then flag="tf";G=tf2ss(G);end + [rows,cols]=size(G); + [A,B,C,D]=abcd(G); + sqD=inv(sqrtm(D'*D)); + //---------------- + [w,rt]=rowcomp(D); + Dorto=w(rt+1:rows,:)'; + // Inner factor: + //------------- + [F,Xc]=lqr(G); + Af=A+B*F;Cf=C+D*F; + Inn=syslin("c",Af,[B*sqD,-pinv(Xc)*C'*Dorto],Cf,[D*sqD,Dorto]); + X=invsyslin(Inn); + //---------------------------- + // Outer factor: + Gbar=invsyslin(syslin("c",Af,B*sqD,F,sqD)); + if flag=="tf" then Inner=ss2tf(Inner);Gbar=ss2tf(Gbar);X=ss2tf(X);end +endfunction diff --git a/modules/cacsd/macros/rowregul.bin b/modules/cacsd/macros/rowregul.bin Binary files differnew file mode 100755 index 000000000..8e002a95b --- /dev/null +++ b/modules/cacsd/macros/rowregul.bin diff --git a/modules/cacsd/macros/rowregul.sci b/modules/cacsd/macros/rowregul.sci new file mode 100755 index 000000000..efc096e5f --- /dev/null +++ b/modules/cacsd/macros/rowregul.sci @@ -0,0 +1,20 @@ +// 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 [Stmp,Ws]=rowregul(Sl,Alfa,Beta); + //[Stmp,Ws]=regul(Sl) computes a polynomial-state-space postfilter + //Ws such that Stmp=Ws*Sl is proper and has D full rank + //Poles at infinity of Sl are moved to -Alfa; + //Zeros at infinity of Sl are moved to -Beta; + //Sl is asummed right invertible i.e. ss2tf(Sl) full row rank + //! + + [Stmp,Ws]=colregul(Sl',Alfa,Beta); + Stmp=Stmp';Ws=Ws'; +endfunction diff --git a/modules/cacsd/macros/sdiff.bin b/modules/cacsd/macros/sdiff.bin Binary files differnew file mode 100755 index 000000000..10a6d13a2 --- /dev/null +++ b/modules/cacsd/macros/sdiff.bin diff --git a/modules/cacsd/macros/sdiff.sci b/modules/cacsd/macros/sdiff.sci new file mode 100755 index 000000000..4ca017960 --- /dev/null +++ b/modules/cacsd/macros/sdiff.sci @@ -0,0 +1,21 @@ +// 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 w=sdiff(z,d) + // time serie diiferencing + // W= (1-B)^d Z + // where B is the backward-shift operator + // and d the difrenecing order + // z : a matrix of size(n1,n2) z(t)=z(:,t) + + [lhs,rhs]=argn(0) + if rhs==1;d=1;end + w=z; + for i=1:d,[n1,n2]=size(w); w=w(:,2:n2)-w(:,1:(n2-1));end +endfunction diff --git a/modules/cacsd/macros/sensi.bin b/modules/cacsd/macros/sensi.bin Binary files differnew file mode 100755 index 000000000..126d5ab34 --- /dev/null +++ b/modules/cacsd/macros/sensi.bin diff --git a/modules/cacsd/macros/sensi.sci b/modules/cacsd/macros/sensi.sci new file mode 100755 index 000000000..3e9bc1cb2 --- /dev/null +++ b/modules/cacsd/macros/sensi.sci @@ -0,0 +1,67 @@ +// 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 [Se,R,T]=sensi(G,Sk,flag) + // [Se,R,T]=sensi(G,Sk) computes sensitivity functions + // If flag='o' or no flag: + // [Se;R;T]= [inv(eye+G*K);K*inv(eye+G*K);G*K*inv(eye+G*K)]; + // + // flag='i' + // [Si,Ri,Ti]= [inv(eye+K*G);G*inv(eye+K*G);K*G*inv(eye+K*G)]; + //! + + [LHS,RHS]=argn(0); + if RHS==2 then flag="o";end + select flag + case "o" + G1=G(1);Sk1=Sk(1); + ssflag=0; + if G1(1)=="r" then G=tf2ss(G);ssflag=1;end + if Sk1(1)=="r" then Sk=tf2ss(Sk);ssflag=ssflag+1;end + [ny,nu]=size(G);Iu=eye(nu,nu);Iy=eye(ny,ny); + Ouy=zeros(nu,ny);Oyu=zeros(ny,nu);Ouu=zeros(nu,nu); + Oyy=zeros(ny,ny); + W1=[Iy,Oyu,Oyy; + Ouy,Iu,Ouy; + -Iy,Oyu,Iy; + Iy,Oyu,Oyy]; + W2=[Iy,-G; + Ouy,Iu; + Iy,Oyu]; + SRT=lft(W1*W2,Sk); + Se=SRT(1:ny,:); + R=SRT((ny+1):(ny+nu),:); + T=SRT((nu+ny+1):(nu+ny+ny),:); + if ssflag >0 then + Se=ss2tf(Se);R=ss2tf(R);T=ss2tf(T); + end + case "i" + G1=G(1);Sk1=Sk(1); + ssflag=0; + if G1(1)=="r" then G=tf2ss(G);ssflag=1;end + if Sk1(1)=="r" then Sk=tf2ss(Sk);ssflag=ssflag+1;end + [ny,nu]=size(G);Iu=eye(nu,nu);Iy=eye(ny,ny); + Ouy=zeros(nu,ny);Oyu=zeros(ny,nu);Ouu=zeros(nu,nu); + Oyy=zeros(ny,ny); + W1=[Iu,-Iu; + Oyu,Oyu; + Ouu,Iu; + Oyu,Oyu]; + W2=[Ouy;Iy;Ouy;Iy]; + W3=[Iu,-Iu]; + P=W1+W2*G*W3; + SRT=lft(P,Sk); + Se=SRT(1:nu,:); + R=SRT((nu+1):(ny+nu),:); + T=SRT((nu+ny+1):(nu+ny+nu),:); + if ssflag >0 then + Se=ss2tf(Se);R=ss2tf(R);T=ss2tf(T); + end + end +endfunction diff --git a/modules/cacsd/macros/sgrid.bin b/modules/cacsd/macros/sgrid.bin Binary files differnew file mode 100755 index 000000000..541bdf4c9 --- /dev/null +++ b/modules/cacsd/macros/sgrid.bin diff --git a/modules/cacsd/macros/sgrid.sci b/modules/cacsd/macros/sgrid.sci new file mode 100755 index 000000000..f1ad08109 --- /dev/null +++ b/modules/cacsd/macros/sgrid.sci @@ -0,0 +1,203 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 sgrid(varargin) + // sgrid(["new",] [,Z,Wn [,colors]]) + // sgrid(Z,Wn [,"new"] [,colors]) + + defaultcolors=[4 12]; + defaultbounds=[-1.6,-1.6;0,1.6]; + rhs=argn(2) + new=%f + if rhs>=1 then + if type(varargin(1))==10 then + if varargin(1)<>"new" then + error(msprintf(_("%s: Wrong value for input argument #%d: ''%s'' expected.\n"),"sgrid",1,"new")) + end + varargin(1)=null() + rhs=rhs-1 + new=%t + end + end + if rhs>=3 then + if type(varargin(3))==10 then + if varargin(3)<>"new" then + error(msprintf(_("%s: Wrong value for input argument #%d: ''%s'' expected.\n"),"sgrid",3,"new")) + end + varargin(3)=null() + rhs=rhs-1 + new=%t + end + end + + defaultwn=%f; + defaultzeta=[0 0.16 0.34 0.5 0.64 0.76 0.86 0.94 0.985 1] + + select rhs + case 0 then //sgrid() or sgrid("new") + defaultwn=%t + zeta = defaultzeta + colors = defaultcolors + case 2 then + zeta = varargin(1) + if type(zeta)<>1|~isreal(zeta) then + error(msprintf(_("%s: Wrong type for input argument #%d : real floating point array expected\n"),"sgrid",1)); + end + wn = varargin(2) + if type(wn)<>1|~isreal(wn) then + error(msprintf(_("%s: Wrong type for input argument #%d : real floating point array expected\n"),"sgrid",2)); + end + colors = defaultcolors + case 3 then + zeta = varargin(1) + if type(zeta)<>1|~isreal(zeta) then + error(msprintf(_("%s: Wrong type for input argument #%d : real floating point array expected\n"),"sgrid",1)); + end + wn = varargin(2) + if type(wn)<>1|~isreal(wn) then + error(msprintf(_("%s: Wrong type for input argument #%d : real floating point array expected\n"),"sgrid",2)); + end + colors = varargin(3) + if type(colors)<>1|~isreal(colors) then + error(msprintf(_("%s: Wrong type for input argument #%d : real floating point array expected\n"),"sgrid",3)); + end + if size(colors,"*")==1 then colors=colors*ones(1,2),end + end + zeta=zeta(zeta>=0&zeta<=1) + fig=gcf(); + immediate_drawing=fig.immediate_drawing; + fig.immediate_drawing="off"; + + axes=gca(); + if new&axes.children<>[] then + delete(axes.children) + end + nc=size(axes.children,"*") + if nc==0 then + axes.data_bounds=defaultbounds + axes.axes_visible="on"; + ax.box="on"; + else + axes.data_bounds=[min(defaultbounds(1,:),axes.data_bounds(1,:)); + max(defaultbounds(2,:),axes.data_bounds(2,:))]; + end + if axes.tight_limits=="off"&axes.auto_ticks(1)=="on" then + xmin=axes.x_ticks.locations(1) + xmax=axes.x_ticks.locations($) + else + xmin=axes.data_bounds(1,1) + xmax=axes.data_bounds(2,1) + end + if axes.tight_limits=="off"&axes.auto_ticks(2)=="on" then + ymin=axes.y_ticks.locations(1) + ymax=axes.y_ticks.locations($) + else + ymin=axes.data_bounds(1,2) + ymax=axes.data_bounds(2,2) + end + + //iso natural frequency curves + if defaultwn then + rmax=sqrt(min(xmin^2+ymin^2,xmin^2+ymax^2)) + rmax=floor(10*rmax)/10; + [xi,xa,np]=graduate(0.2,rmax,8,12) + wn=linspace(xi,xa,np) + end + wn=wn(wn>=0) + t=linspace(%pi/2,1.5*%pi,200) + chart_handles=[] + for i=1:size(wn,"*") + xpoly(wn(i)*cos(t),wn(i)*sin(t)) + ec=gce(); + ec.display_function = "formatSgridFreqTip"; + ec.display_function_data = wn(i); + + ec.foreground=colors(1), + ec.line_style=7; + ec.clip_state="clipgrf"; + + lab=msprintf("%.2g",wn(i)) + r=xstringl(0,wn(i),lab) + if %t then + xstring(-r(3),wn(i),lab) + es1=gce(); + es1.font_foreground=colors(1), + es1.clip_state="clipgrf"; + xstring(-r(3),-wn(i)-r(4),lab) + es2=gce(); + es2.font_foreground=colors(1), + es2.clip_state="clipgrf"; + e=glue([es2 es1 ec]) + else + xstring(-wn(i)-r(3),0,lab) + es1=gce(); + es1.font_foreground=colors(1), + es1.clip_state="clipgrf"; + e=glue([es1 ec]); + end + chart_handles=[e chart_handles] + end + //iso damping factor curves + angl=acos(zeta) + + for i=1:size(zeta,"*") + lab=string(zeta(i)) + rect=xstringl(0,0,lab) + + sa=sin(angl(i));ca=cos(angl(i)) + if sa==0 then sa=%eps;end + if ca==0 then ca=%eps;end + r=min(-ymin/sa,-xmin/ca) + + xpoly([0 -r*ca],[0 -r*sa]) + ec=gce(); + ec.display_function = "formatSgridDampingTip"; + ec.display_function_data = zeta(i); + + ec.foreground=colors(2), + ec.line_style=7; + ec.clip_state="clipgrf"; + if -ymin/sa<-xmin/ca + r1=r-rect(4)/sa + xstring(-r1*ca-rect(3),-r1*sa,lab) + else + xstring(-r*ca+0.02*rect(3),-r*sa,lab) + end + es=gce(); + es.font_foreground=colors(2), + es.clip_state="clipgrf"; + chart_handles=[glue([es ec]),chart_handles] + + r=min(ymax/sa,-xmin/ca) + xpoly([0 -r*ca],[0 r*sa]) + ec=gce(); + ec.display_function = "formatSgridDampingTip"; + ec.display_function_data = zeta(i); + + ec.foreground=colors(2), + ec.line_style=7; + ec.clip_state="clipgrf"; + if ymax/sa<-xmin/ca then + xstring(-r*ca-rect(3),r*sa-rect(4),lab) + else + xstring(-r*ca,r*sa,lab) + end + es=gce(); + es.font_foreground=colors(2), + es.clip_state="clipgrf"; + chart_handles=[glue([es ec]),chart_handles] + end + chart_handles=glue(chart_handles) + //reorder axes children to make chart drawn before the black previously + // drawn curves if any + for k=1:nc + swap_handles(axes.children(k),axes.children(k+1)) + end + fig.immediate_drawing=immediate_drawing; + show_window() +endfunction diff --git a/modules/cacsd/macros/show_margins.bin b/modules/cacsd/macros/show_margins.bin Binary files differnew file mode 100755 index 000000000..d6ab09f29 --- /dev/null +++ b/modules/cacsd/macros/show_margins.bin diff --git a/modules/cacsd/macros/show_margins.sci b/modules/cacsd/macros/show_margins.sci new file mode 100755 index 000000000..1f6bd1612 --- /dev/null +++ b/modules/cacsd/macros/show_margins.sci @@ -0,0 +1,93 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - Author: Serge Steer +// +// 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 show_margins(h,typ) + if argn(2)<2 then typ="bode",end + if and(typ<>["nyquist","bode"]) then + error(msprintf(_("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),.. + "show_margins",2,"""nyquist"", ""bode""")) + end + + fig=gcf(); + immediate_drawing=fig.immediate_drawing; + fig.immediate_drawing="off"; + + clf(); + if typ=="bode" then + bode(h) + f=gcf(); + axg=f.children(2); + axp=f.children(1); + fmin=min(axg.x_ticks.locations); + fmax=max(axg.x_ticks.locations); + gmin=min(axg.y_ticks.locations); + gmax=max(axg.y_ticks.locations); + pmin=min(axp.y_ticks.locations); + pmax=max(axp.y_ticks.locations); + + [gm,fr]=g_margin(h) + sca(axp); + xpoly([fmin;fmax],[-180;-180]) + e=gce();e.foreground=color("red");e.line_style=4; + if fr<>[] then + xpoly([fr;fr],[pmin;pmax]) + e=gce();e.foreground=color("red");e.line_style=4; + sca(axg); + xpoly([fr;fr],[gmin;gmax]) + e=gce();e.foreground=color("red");e.line_style=4; + xpoly([fr;fr],[-gm;0]) + e=gce();e.foreground=color("red");e.thickness=2; + end + + [phm,fr]=p_margin(h) + sca(axg); + xpoly([fmin;fmax],[0;0]) + e=gce();e.foreground=color("blue");e.line_style=4; + if fr<>[] then + xpoly([fr;fr],[gmin;gmax]) + e=gce();e.foreground=color("blue");e.line_style=4; + sca(axp); + xpoly([fr;fr],[pmin;pmax]) + e=gce();e.foreground=color("blue");e.line_style=4; + xpoly([fr;fr],[-180;phm-180]) + e=gce();e.foreground=color("blue");e.thickness=2; + end + else + if typeof(h)=="state-space" then + h=ss2tf(h); + end + nyquist(h) + ax=gca(); + [gm,fr]=g_margin(h) + xpoly([min(ax.x_ticks.locations);0],[0;0]); + e=gce();e.foreground=color("blue");e.line_style=4; + if fr<>[] then + if h.dt=="c" then + f=horner(h,2*%i*%pi*fr) + else + dt=h.dt;if dt=="d" then dt=1,end + f=horner(h,exp(2*%i*%pi*fr*dt)) + end + xpoly([real(f);0],[0;0]); + e=gce();e.foreground=color("blue");e.thickness=2; + end + [phm,fr]=p_margin(h) + //unit circle + t=linspace(0,2*%pi,100); + xpoly(sin(t),cos(t)) + e=gce();e.foreground=color("red");e.line_style=4; + if fr<>[] then + t=phm*%pi/180+%pi; + xpoly([cos(t);0],[sin(t);0]) + e=gce();e.foreground=color("red");e.thickness=2; + end + end + fig.immediate_drawing=immediate_drawing; + +endfunction diff --git a/modules/cacsd/macros/sm2des.bin b/modules/cacsd/macros/sm2des.bin Binary files differnew file mode 100755 index 000000000..6aa30d3b4 --- /dev/null +++ b/modules/cacsd/macros/sm2des.bin diff --git a/modules/cacsd/macros/sm2des.sci b/modules/cacsd/macros/sm2des.sci new file mode 100755 index 000000000..7c87c5b3a --- /dev/null +++ b/modules/cacsd/macros/sm2des.sci @@ -0,0 +1,38 @@ +// 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 des=sm2des(sysmat,n) + // Generalized system-matrix to descriptor + // sysmat=[-s E + A , B; C , D] + // des=list('des',A,B,C,D,E) + // n=size(A) (assumed square) (optional parameter) + + [LHS,RHS]=argn(0) + [nl,nc]=size(sysmat); + E=-coeff(sysmat,1); + if RHS==1 then + k=nc;n=k; + while E(:,k)==0*E(:,k) + k=k-1;n=k; + end + l=nl;n1=l; + while E(l,:)==0*E(l,:) + l=l-1;n1=l; + end + if n1<>n then + warning(msprintf(gettext("%s: Cannot find the state dimension.\n"),"sm2des")); + end + end + E=E(1:n,1:n); + A=coeff(sysmat(1:n,1:n),0); + B=coeff(sysmat(1:n,n+1:nc),0); + C=coeff(sysmat(n+1:nl,1:n),0); + D=coeff(sysmat(n+1:nl,n+1:nc),0); + des=tlist(["des","A","B","C","D","E"],A,B,C,D,E); +endfunction diff --git a/modules/cacsd/macros/sm2ss.bin b/modules/cacsd/macros/sm2ss.bin Binary files differnew file mode 100755 index 000000000..1ed039c15 --- /dev/null +++ b/modules/cacsd/macros/sm2ss.bin diff --git a/modules/cacsd/macros/sm2ss.sci b/modules/cacsd/macros/sm2ss.sci new file mode 100755 index 000000000..a872dcf50 --- /dev/null +++ b/modules/cacsd/macros/sm2ss.sci @@ -0,0 +1,42 @@ +// 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 des=sm2ss(sysmat) + // Generalized system-matrix to descriptor + // sysmat=[-s I + A , B; C , D] + // [n,n]=size(A) + + if typeof(sysmat)<>"polynomial" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Polynomial array expected.\n"),"sm2ss",1)) + end + [nl,nc]=size(sysmat); + E=-coeff(sysmat,1); + k=nc; + while and(E(:,k)==0*E(:,k)) + k=k-1;n=k; + end + l=nl; + while and(E(l,:)==0*E(l,:)) + l=l-1;n1=l; + end + + if n1<>n then + warning(msprintf(gettext("%s: Cannot find the state dimension.\n"),"sm2ss")); + end + + E=E(1:n,1:n); + if E<>eye(n,n) then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space system expected.\n"),"sm2ss",1)); + end + A=coeff(sysmat(1:n,1:n),0); + B=coeff(sysmat(1:n,n+1:nc),0); + C=coeff(sysmat(n+1:nl,1:n),0); + D=coeff(sysmat(n+1:nl,n+1:nc),0); + des=syslin([],A,B,C,D); +endfunction diff --git a/modules/cacsd/macros/smga.bin b/modules/cacsd/macros/smga.bin Binary files differnew file mode 100755 index 000000000..d07cae09e --- /dev/null +++ b/modules/cacsd/macros/smga.bin diff --git a/modules/cacsd/macros/smga.sci b/modules/cacsd/macros/smga.sci new file mode 100755 index 000000000..7be7fc4bb --- /dev/null +++ b/modules/cacsd/macros/smga.sci @@ -0,0 +1,41 @@ +// 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 [a,b1,b2,c1,c2,d11,d12,d21,d22]=smga(slp,r) + //Matrix extractions (for use with h_inf,lft and other); + // Utility function + + + select typeof(slp) + case "state-space" then + p=r(2),r=r(1), + [s1,s2,t]=size(slp); + [a,b,c,d]=abcd(slp), + b1=b(:,1:s2-p); + b2=b(:,s2-p+1:s2), + c1=c(1:s1-r,:); + c2=c(s1-r+1:s1,:), + d11=coeff(d(1:s1-r,1:s2-p),0), + d12=coeff(d(1:s1-r,s2-p+1:s2),0), + d21=coeff(d(s1-r+1:s1,1:s2-p),0), + d22=coeff(d(s1-r+1:s1,s2-p+1:s2),0) + case "rational" then + [nl,nk]=size(slp); + k1=1:nl-r(1); + k2=nl-r(1)+1:nl; + m1=1:nk-r(2); + m2=nk-r(2)+1:nk; + a=slp(k1,m1); //p11 + b1=slp(k1,m2); //p12 + b2=slp(k2,m1); //p21 + c1=slp(k2,m2); //p22 + c2=[] + d11=[],d12=[],d21=[],d22=[] + end +endfunction diff --git a/modules/cacsd/macros/solve.bin b/modules/cacsd/macros/solve.bin Binary files differnew file mode 100755 index 000000000..da57d13c6 --- /dev/null +++ b/modules/cacsd/macros/solve.bin diff --git a/modules/cacsd/macros/solve.sci b/modules/cacsd/macros/solve.sci new file mode 100755 index 000000000..6c89ed65d --- /dev/null +++ b/modules/cacsd/macros/solve.sci @@ -0,0 +1,35 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque , Serge STEER +// +// 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 x=solve(a,b) + // x=solve(A,b) solves A*x = b when A is an upper triagular matrix + // made of character strings. + //! + + [na,ma]=size(a),[mb,nb]=size(b) + pivot=a(na,na); + if pivot<>"1" then + for k=1:nb, + x(1,k)=ldivf(pivot,b(na,k)) + end + else + x=b(na,:) + end + // update + if na>1 then + for l=1:na-1, + pivot=mulf("-1",a(l,na)) + for k=1:nb, + b(l,k)=addf(b(l,k),mulf(pivot,x(k))) + end + end + y=solve(a(1:na-1,1:na-1),b(1:na-1,:)) + x=[y;x] + end +endfunction diff --git a/modules/cacsd/macros/specfact.bin b/modules/cacsd/macros/specfact.bin Binary files differnew file mode 100755 index 000000000..7cc8d4902 --- /dev/null +++ b/modules/cacsd/macros/specfact.bin diff --git a/modules/cacsd/macros/specfact.sci b/modules/cacsd/macros/specfact.sci new file mode 100755 index 000000000..56494b4ba --- /dev/null +++ b/modules/cacsd/macros/specfact.sci @@ -0,0 +1,16 @@ +// 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 [w0,l]=specfact(a,b,c,d) + + r=d+d';w0=sqrtm(r); + p=ricc(a-b/r*c,-b/r*b',c'/r*c,"cont"); + //a'*p+p*a+(c'-p*b)*inv(r)*(c-b'*p) is zero + l=w0\(c-b'*p) +endfunction diff --git a/modules/cacsd/macros/ss2des.bin b/modules/cacsd/macros/ss2des.bin Binary files differnew file mode 100755 index 000000000..fa8a1cea8 --- /dev/null +++ b/modules/cacsd/macros/ss2des.bin diff --git a/modules/cacsd/macros/ss2des.sci b/modules/cacsd/macros/ss2des.sci new file mode 100755 index 000000000..b225d7cbc --- /dev/null +++ b/modules/cacsd/macros/ss2des.sci @@ -0,0 +1,35 @@ +// 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 S=ss2des(Sl,flag) + // Returns S=list('des',A,B,C,D,E) for Sl a state-space + // system with Ds polynomial. + // if flag=="withD" a maximal rank D matrix is returned in S + // otherwise D=0; + // Copyright INRIA + [LHS,RHS]=argn(0); + if RHS==1 then flag=[];end + if RHS==2&flag<>"withD" then warning(msprintf(gettext("%s: Wrong value for input argument #%d: ''%s'' expected.\n"),"ss2des",2,"withD"));end + Ds=Sl(5); + if type(Ds)==1 then + if norm(Ds,1)==0 then S=Sl;return;end + if norm(Ds,1)<>0 then Sl(5)=Ds+poly(0,"s")*0*Ds;end + end + [A2,B2,C2,Ds]=Sl(2:5); + if flag=="withD" then D=coeff(Ds,0);Ds=Ds-D;end + [N,B1,C1]=pol2des(Ds); + [n1,n1]=size(N); + [n2,n2]=size(A2); + E=[N,0*ones(n1,n2);0*ones(n2,n1),eye(n2,n2)]; + A=[eye(N),0*ones(n1,n2);0*ones(n2,n1),A2]; + C=[C1,C2]; + B=[B1;B2]; + if flag<>"withD" then D=0*C*B;end + S=tlist(["des","A","B","C","D","E"],A,B,C,D,E); +endfunction diff --git a/modules/cacsd/macros/ss2ss.bin b/modules/cacsd/macros/ss2ss.bin Binary files differnew file mode 100755 index 000000000..ec3a69df1 --- /dev/null +++ b/modules/cacsd/macros/ss2ss.bin diff --git a/modules/cacsd/macros/ss2ss.sci b/modules/cacsd/macros/ss2ss.sci new file mode 100755 index 000000000..cbf3351e1 --- /dev/null +++ b/modules/cacsd/macros/ss2ss.sci @@ -0,0 +1,101 @@ +// 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 [Sl1,right,left]=ss2ss(Sl,T,F,G,flag) + // State-space to state-space conversion + // Returns the linear system Sl1=[A1,B1,C1,D1] + // where A1=inv(T)*A*T,B1=inv(T)*B,C1=C*T,D1=D. + // Optional parameters F and G are state feedback + // and output injection respectively. For example, + // Sl1=ss2ss(Sl,T,F) returns Sl1=[A1,B1,C1,D1] with + // A1=inv(T)*(A+B*F)*T;B1=inv(T)*B;C1=(C+D*F)*T;D1=D; + // If F is given as input then right is a non singular + // linear system such that Sl1=Sl*right. + // Sl1*invsyslin(right) is a factorization of Sl. + // Idem for left: if F and G are given, Sl1=left*Sl*right. + // Example: Sl=ssrand(2,2,5); trzeros(Sl); + // Sl1=ss2ss(Sl,rand(5,5),rand(2,5),rand(5,2)); + // trzeros(Sl1), trzeros(rand(2,2)*Sl1*rand(2,2)) + // See also : projsl + + [A,B,C,D]=abcd(Sl); + [LHS,RHS]=argn(0); + select RHS + case 2 then + Sl1=syslin(Sl(7),inv(T)*A*T,inv(T)*B,C*T,D); + right=eye(A);left=right; + case 3 then + A1=A+B*F;C1=C+D*F; + A1=inv(T)*A1*T;B1=inv(T)*B;C1=C1*T;D1=D + Sl1=syslin(Sl(7),A1,B1,C1,D1); + right=syslin(Sl(7),A+B*F,B,F,eye(F*B)); + left=eye(size(C,1),size(C,1)); + case 4 then + A1=A+B*F+G*C+G*D*F;C1=C+D*F;B1=B+G*D + A1=inv(T)*A1*T;B1=inv(T)*B1;C1=C1*T;D1=D + Sl1=syslin(Sl(7),A1,B1,C1,D1); + right=syslin(Sl(7),A+B*F,B,F,eye(F*B)); + // Warning left is computed as [ At + G*Ct,G;Ct,I] + // where [At Bt; Ct Dt] is Sl1*right + At=A+B*F; Ct=C+D*F + left=syslin(Sl(7),At+G*Ct,G,Ct,eye(Ct*G)); + case 5 then + if flag==1 then + // x in R^n , y in R^p, u in R^m + // output injection [ A + GC, (B+GD,-G)] + // [ C , (D , 0)] + // then feeback ( since output injection increase the + // size of the feedback the F matrix must be of size + // (m+p,n) --> F=[F1;F2] with F1 (m,n) and F2 (p,n) + // + // Sl1= [ A+GC +BF1+G*D*F1 -GF2, (B+GD,-G)] + // [ C+D*F1 , (D , 0)] + // + // We have then the following property + // Sl1 equiv left*sysdiag(sys,eye(p,p))*right + // + // + n=size(A,"r");p=size(C,"r"); + A1=A+G*C+[B+G*D,-G]*F;B1=[B+G*D,-G];C1=C+[D,zeros(p,p)]*F; + D1=[D,zeros(p,p)]; + A1=inv(T)*A1*T;B1=inv(T)*B1;C1=C1*T;D1=D1 + Sl1=syslin(Sl(7),A1,B1,C1,D1); + left=syslin(Sl(7),A+G*C,[G,-G],C,[eye(p,p),zeros(p,p)]); + // Now we compute the right associated to left*Sl1 + A1=A+G*C;B1=[B+G*D,-G];C1=C;D1=[D,zeros(p,p)]; + right=syslin(Sl(7),A1+B1*F,B1,F,eye(F*B1)); + return + end + if flag==2 then + // x in R^n , y in R^p, u in R^m + // feedback first F of size(m,n) + // [ A+BF,B] + // [ C+DF,D] + // then output injection + // Sl1= [ A+GC +BF+G*D*F, (B+GD,-G)] + // [ C+D*F , (D , 0)] + // this is a generalization of the case 4 + // We have then the following property + // Sl1 equiv left*sysdiag(sys*right,eye(p,p))) + // + A1=A+B*F+G*C+G*D*F; + C1=C+ D*F; + D1=[D,zeros(p,p)]; + B1=[B+G*D,-G]; + A1=inv(T)*A1*T;B1=inv(T)*B1;C1=C1*T;D1=D1 + Sl1=syslin(Sl(7),A1,B1,C1,D1); + right=syslin(Sl(7),A+B*F,B,F,eye(F*B)); + // Warning left is computed as [ At + G*Ct,(G,-G); + // [ Ct ,(I, 0)] + // where [At Bt; Ct Dt] is Sl1*right + At=A+B*F; Ct=C+D*F + left=syslin(Sl(7),At+G*Ct,[G,-G],Ct,[eye(Ct*G),zeros(Ct*G)]); + end + end +endfunction diff --git a/modules/cacsd/macros/ss2tf.bin b/modules/cacsd/macros/ss2tf.bin Binary files differnew file mode 100755 index 000000000..8a8286a0b --- /dev/null +++ b/modules/cacsd/macros/ss2tf.bin diff --git a/modules/cacsd/macros/ss2tf.sci b/modules/cacsd/macros/ss2tf.sci new file mode 100755 index 000000000..8e764387d --- /dev/null +++ b/modules/cacsd/macros/ss2tf.sci @@ -0,0 +1,150 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 1985-2010 - INRIA - Serge Steer +// +// 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 [h,num,den]=ss2tf(sl,rmax) + // State-space to transfer function. + // Syntax: + // h=ss2tf(sl) + // h=ss2tf(sl,'b') + // h=ss2tf(sl,rmax) + // + // sl : linear system (syslin list) + // h : transfer matrix + // rmax : optional parameter controlling the conditioning in + // block diagonalization method is used (If 'b' is entered + // a default value is used) + // Method: By default, one uses characteristic polynomial and + // det(A+Eij)=det(A)+C(i,j) where C is the adjugate matrix of A + // Other method used : block-diagonalization (generally + // this gives a less accurate result). + // + //! + + if type(sl)==1|type(sl)==2 then + h=sl + return + end + if typeof(sl)<>"state-space" then + error(msprintf(_("%s: Wrong type for input argument #%d: State-space form expected.\n"),"ss2tf",1)); + end + //Handle special cases (no input, no output, no state) + if sl.B==[] then h=sl.D;num=sl.D;den=eye(sl.D);return;end + if sl.C==[] then h=sl.D;num=sl.D;den=eye(sl.D);return;end + if size(sl.A,"*")==0 then //no state + h=sl.D + return + end + + //Determine the rational fraction formal variable name + domaine=sl.dt + if type(domaine)==1 then var="z";end + if domaine=="c" then var="s";end; + if domaine=="d" then var="z";end; + if domaine==[] then + var="s"; + if type(sl.D)==2 then var=varn(sl.D);end + end + + //Determine the algorithm + [lhs,rhs]=argn(0); + meth="p"; + if rhs==2 then + if type(rmax)==10 then + meth=part(rmax,1); + if and(meth<>["p","b"]) then + error(msprintf(_( "%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),"ss2tf",1,"''p'',''b''")); + end + rhs=1; + else + meth="b"; + end + end + + select meth + case "b" // Block diagonalization + Leverrier method + a=sl.A; + [n1,n1]=size(a); + z=poly(0,var); + //block diagonal decomposition of the state matrix + if rhs==1 then + [a,x,bs]=bdiag(a); + else + [a,x,bs]=bdiag(a,rmax); + end + k=1;m=[];v=ones(1,n1);den=1; + for n=bs' //loop on blocks + k1=k:k-1+n; + // Leverrier algorithm + h=z*eye(n,n)-a(k1,k1); + f=eye(n,n); + for kl=1:n-1, + b=h*f; + d=-sum(diag(b))/kl; + f=b+eye()*d; + end + d=sum(diag(h*f))/n; + // + den=den*d; + l=[1:k-1,k+n:n1]; + if l<>[] then v(l)=v(l)*d;end + m=[m,x(:,k1)*f]; + k=k+n; + end + + if lhs==3 then + h=sl.D, + num=sl.C*m*diag(v)*(x\sl.B); + else + m=sl.C*m*diag(v)*(x \ sl.B)+sl.D*den; + [m,den]=simp(m,den*ones(m)) + h=syslin(domaine,m,den) + end + + case "p" then //Adjugate matrix method + Den=poly(sl.A,var) //common denominator + + na=degree(Den);den=[]; + [m,n]=size(sl.D) + c=sl.C + for l=1:m //loop on outputs + [m,i]=max(abs(c(l,:))); + if m<>0 then + ci=c(l,i) + t=eye(na,na)*ci; + t(i,:)=[-c(l,1:i-1), 1, -c(l,i+1:na)] + al=sl.A*t; + + t=eye(na,na)/ci; + t(i,:)=[c(l,1:i-1)/ci, 1, c(l,i+1:na)/ci] + al=t*al;ai=al(:,i), + b=t*sl.B + + for k=1:n //loop on inputs + al(:,i)=ai+b(:,k); + [nlk,dlk]=simp(poly(al,var),Den) + den(l,k)=dlk; + num(l,k)=-(nlk-dlk)*ci; + end + else + num(l,1:n)=0*ones(1,n); + den(l,1:n)=ones(1,n); + end + end + if lhs==3 then + h=sl.D; + else + w=num./den+sl.D; + if type(w)==1 then + h=w; //degenerate case + else + h=syslin(domaine,w); + end + end + end +endfunction diff --git a/modules/cacsd/macros/ssrand.bin b/modules/cacsd/macros/ssrand.bin Binary files differnew file mode 100755 index 000000000..5b613d69d --- /dev/null +++ b/modules/cacsd/macros/ssrand.bin diff --git a/modules/cacsd/macros/ssrand.sci b/modules/cacsd/macros/ssrand.sci new file mode 100755 index 000000000..344e3465d --- /dev/null +++ b/modules/cacsd/macros/ssrand.sci @@ -0,0 +1,275 @@ +// 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 [sl,U]=ssrand(nout,nin,nstate,flag) + //flag=list('co',dim_cont_subs) + //flag=list('uo',dim_unobs_subs) + //*******************controllable-unobservable*********** + //display a general Kalman form + //flag=list('ncno',dim_cno,dim_ncno,dim_co,dim_nco) + // + // (A,B,C) U-similar to + // + // [*,*,*,*; [*; + // [0,*,*,*; [0; + // A= [0,0,*,*; B= [*; + // [0,0,0,*] [0]; + // + // C= [0,0,*,*] D= [0] + // + // (A11,B1) --> controllable, unobservable modes , dimension flag(2) + // (A22,B2) --> uncontrolable,unobservables modes, dimension flag(3) + // (A33,B3) --> controllable,observable modes , dimension flag(4) + // (A44,B4) --> uncontrollable,observable modes, dimension flag(5) + //*******************stabilizability********************* + //flag=list('st',dim_cont_subs,dim_stab_subs,dim_stab0) + // dim_cont_subs<=dim_stab_subs<=dim_stab0 + //pair (A,B) U-similar to: + // [*,*,*,*; [*; + // [0,s,*,*; [0; + //A= [0,0,i,*; B=[0; + // [0,0,0,u] [0] + // + // (A11,B1) controllable s=stable matrix i=neutral matrix u=unstsble matrix + //********************detectability*********************** + //flag=list('dt',dim_inst_unob,dim_instb0,dim_unobs) + // dim_inst_unob<=dim_instb0<=dim_unobs + // + //pair (A,C) U-similar to: + // + // [u,*,*,*; + // [0,i,*,*; + //A= [0,0,s,*; + // [0,0,0,*] + // + //C= [0,0,0,*] + // + // (A44,C4) observable s=stable matrix i=neutral matrix u=unstsble matrix + // + //********************output-nulling*********************** + //flag=list('on',nr,ng,ng0,nv,rk) + // nr<=ng<=ng0<=nv<=nstate and rk<=nu (rk<nu if nr>0) + // nstate-nv>=rk ny>=rk + // + //system (A,B,C,D) U-equivalent to + // + // [*,*,*,*,*; [0,*; + // [0,s,*,*,*; [0,0; + //A= [0,0,n,*,*; B=[0,0; + // [0,0,0,u,*; [0,0; + // [*,*,*,*,*] [*,0] + // + //C= [*,*,*,*,*] D=[*,0] + // + // with (A11,B21) controllable + // A22 stable + // A33 neutral + // A44 unstable + // [B51;D11] full column rank + // range([A51,A52,A53,A54;C1,C2,C3,C4]) included in range([B51;D11]) + // dimension A11=nr + // A22=ng-nr + // A33=ng0-ng + // A44=nv-ng0 + // A55=nstate-nv + // column dimension of B1. = column dimension of D1. =rk + //**********************'unknown-input'*********************** + //flag=list('ui',nw,nwu,nwui,nwuis,rk) + // nw<=nwu<=nwui<=nwuis<=nstate rk<=nout + // + //system (A,B,C,D) U-equivalent to + // + // [*,*,*,*,*; [*; + // [*,u,*,*,*; [*; + //A= [*,0,i,*,*; B=[*; + // [*,0,0,s,*; [*; + // [*,0,0,0,*] [*] + // + // [0,0,0,0,*; [0; + //C= [*,0,0,0,0] D=[*; + // + // with (A55,C15) observable + // [C21,d2] full row-rank + // row-image([[A21;A31;A41;A51]],[B2;B3;B4;B5]) + // included in row-image([C21,D2]); + // A22 unstable + // A33 neutral + // A44 stable + // dimension A11=nw + // dimension A22=nwu-nw + // dimension A33=nwui-nwu + // dimension A44=nwuis-nwui + // row dimension C2.= row dimension of D2. =rk + //*************************************************************** + + deff("[w]=st_able(w,margin)","if w~=[] then w=w-(max(real(spec(w)))+margin)*eye();end") + margin=0.5; //M "stable" will mean real-part(M) < -margin + [lhs,rhs]=argn(0) + //rand('seed',0) + rand("normal") + if rhs==3 then flag=[];end + select flag(1) + case [] + sl=syslin("c",rand(nstate,nstate),rand(nstate,nin),rand(nout,nstate),.. + zeros(nout,nin),zeros(nstate,1));U=eye(nstate,nstate); + case "fullV" + //C^(-1)(D) = X + rd=flag(2) //rank(D) needs rd<nin + sl=syslin("c",rand(nstate,nstate),rand(nstate,nin),... + [rand(rd,nstate);zeros(nout-rd,nstate)],[rand(rd,nin);zeros(nout-rd,nin)]); + case "noW" + // B ker(D)=0 + rd=flag(2) //rank(D) needs nout>rd or C=0 + sl=syslin("c",rand(nstate,nstate),[zeros(nstate,nin-rd),rand(nstate,rd)],... + rand(nout,nstate),[zeros(nout,nin-rd),rand(nout,rd)]); + case "fullW" + //admits polynomial inverse + iv=rand(nin,nout) + for k=1:nstate + iv=iv+(%s^k)*rand(nin,nout); + end + sl=minss(inv(tf2ss(iv))); + case "co" + nc=flag(2); + iii=nstate-nc; + a=[rand(nc,nc),rand(nc,iii); + zeros(iii,nc),rand(iii,iii)]; + b=[rand(nc,nin); + zeros(iii,nin)];c=rand(nout,nstate); + U=rand(nstate,nstate); + sl=ss2ss(syslin("c",a,b,c),U); + case "uo" + no=flag(2) + iii=nstate-no; + a=[rand(no,no),rand(no,iii);zeros(iii,no),rand(iii,iii)]; + c=[zeros(nout,no),rand(nout,iii)];b=rand(nstate,nin); + U=rand(nstate,nstate); + sl=ss2ss(syslin("c",a,b,c),U); + case "ncno" + cno=flag(2);ncno=flag(3);co=flag(4);nco=flag(5); + a=sysdiag(rand(cno,cno),rand(ncno,ncno),rand(co,co),rand(nco,nco)); + b=[rand(cno,nin); + zeros(ncno,nin); + rand(co,nin); + zeros(nco,nin)]; + c=[zeros(nout,cno+ncno),rand(nout,nstate-cno-ncno)]; + U=rand(nstate,nstate); + sl=ss2ss(syslin("c",a,b,c),U); + case "st" + [nc,ns,ns0]=flag(2:4);nsc=ns-nc;nsc0=ns0-ns;nxs=nstate-ns; + a=sysdiag(rand(nc,nc),imag_axis(ns-nc,ns0-ns,nstate-ns0)), + b=[rand(nc,nin);zeros(nstate-nc,nin)]; + c=rand(nout,nstate); + U=rand(nstate,nstate); + sl=ss2ss(syslin("c",a,b,c),U); + case "dt" + [n1,n2,n3]=flag(2:4); + w=imag_axis(n3-n2,n2-n1,n1,"uis"); + a=sysdiag(w,rand(nstate-n3,nstate-n3)); + c=[zeros(nout,n3),rand(nout,nstate-n3)];b=rand(nstate,nin); + U=rand(nstate,nstate); + sl=ss2ss(syslin("c",a,b,c),U); + case "on" + [nr,ng,ng0,nv,rk]=flag(2:6); + p1=1;p2=1; + a11=sysdiag(rand(nr,nr),imag_axis(ng-nr,ng0-ng,nv-ng0)); + a12=rand(nv,nstate-nv); + a21=rand(nstate-nv,nv);a22=rand(nstate-nv,nstate-nv); + b11=zeros(nv,rk);b12=[rand(nr,nin-rk);zeros(nv-nr,nin-rk)]; + b22=zeros(nstate-nv,nin-rk);d2=zeros(nout,nin-rk); + c1=rand(nout,nv);c2=rand(nout,nstate-nv); + b21d1=rand(nstate-nv+nout,rk); + if rk<>0 then a21c1=b21d1*rand(rk,nv);else a21c1=c1;end + b21=b21d1(1:nstate-nv,:);d1=b21d1(nstate-nv+1:nstate-nv+nout,:); + a21=a21c1(1:nstate-nv,:);c1=a21c1(nstate-nv+1:nstate-nv+nout,:); + + if rk>=nout then + error(msprintf(gettext("%s: Wrong values for input argument #%d: you must choose rk<nout.\n"),"ssrand",4)) + end + // if rk>=nout then j=-b21*pinv(d1);a22=-j*c2;end + [pp,qq]=size(a21);a21(p1+1:pp,1:nv)=0*a21(p1+1:pp,1:nv); + b21(p1+1:pp,:)=0*b21(p1+1:pp,:); + [pp,qq]=size(c1);c1(p2+1:pp,:)=0*c1(p2+1:pp,:); + d1(p2+1:pp,:)=0*d1(p2+1:pp,:); + w=syslin("c",[a11,a12;a21,a22],[b11,b12;b21,b22],[c1,c2],[d1,d2]); + U=eye(nstate,nstate);sl=ss2ss(w,U); + case "ri" + [nv,nr,nw,rk]=flag(2:5) + n1=nv-nr;n2=nr;n3=nstate-nv; + a11=rand(n1,n1);a12=zeros(n1,n2);a21=rand(n2,n1); + a22=rand(n2,n2);a23=rand(n2,n3); + a33=rand(n3,n3); + b2=rand(n2,nin);b31=rand(n3,rk);b32=zeros(n3,nin-rk); + d1=rand(nout,rk);d2=zeros(nout,nin-rk); + c3=rand(nout,n3); + a31=b31*rand(rk,n1);a32=b31*rand(rk,n2); + c1=d1*rand(rk,n1);c2=d1*rand(rk,n2); + a13=rand(n1,nout)*c3;b1=rand(n1,nout)*[d1,d2]; + b3=[b31,b32];d=[d1,d2] + sl=syslin("c",[a11,a12,a13;a21,a22,a23;a31,a32,a33],[b1;b2;b3],[c1,c2,c3],d); + case "ui" + [nw,nwu,nwui,nwuis,rk]=flag(2:6) + a11=rand(nw,nw); + a22=sysdiag(imag_axis(nwu-nw,nwui-nwu,nwuis-nwui,"uis"),... + rand(nstate-nwuis,nstate-nwuis)) + a12=rand(nw,nstate-nw); + b1=rand(nw,nin); + c21d2=rand(rk,nw+nin); + a21b2=rand(nstate-nw,rk)*c21d2; + a21=a21b2(:,1:nw);b2=a21b2(:,nw+1:nw+nin); + c21=[c21d2(:,1:nw),zeros(rk,nwuis-nw)]; + d2=c21d2(:,nw+1:nw+nin); + c11=zeros(nout-rk,nwuis);c12=rand(nout-rk,nstate-nwuis); + d1=zeros(nout-rk,nin);c22=zeros(rk,nstate-nwuis); + w=syslin("c",[a11,a12;a21,a22],[b1;b2],[c11,c12;c21,c22],[d1;d2]); + U=rand(nstate,nstate); + sl=ss2ss(w,U); + end + rand("uniform"); + //rand('seed',0) + +endfunction +function w=imag_axis(ns,nn,nu,flag); + //w=random block diagonal matrix with ns stable evals + //nn imaginary-axis evals and nu unstable evals. + //flag='uis' blocks along main diagonal appear in the + // order "unstable", "imaginary axis", "stable". + [LHS,RHS]=argn(0); + if RHS==3 then flag="siu";end + if flag=="siu" then + deff("[w]=st_able(w,margin)","if w~=[] then w=w-(max(real(spec(w)))+margin)*eye();end") + margin=0.5; //M "stable" will mean real-part(M) < -margin + w=[];k=int(nn/2); + rand("normal"); + //rand('seed',0); + w=sysdiag(w,st_able(rand(ns,ns),margin)); + x=rand(1,k); + for u=x + w=sysdiag(w,[u,-2*u;u,-u]);end + if abs(2*k-nn)>1.d-5 then w=sysdiag(w,0);end + w=sysdiag(w,-st_able(rand(nu,nu),margin)); + rand("uniform"); + //rand('seed',0); + return + end + if flag=="uis" then + deff("[w]=st_able(w,margin)","if w~=[] then w=w-(max(real(spec(w)))+margin)*eye();end") + w=[];k=int(nn/2); + rand("normal"); + //rand('seed',0); + w=sysdiag(w,-st_able(rand(nu,nu),margin)); + x=rand(1,k); + for u=x + w=sysdiag(w,[u,-2*u;u,-u]);end + if abs(2*k-nn)>1.d-5 then w=sysdiag(w,0);end + w=sysdiag(w,st_able(rand(ns,ns),margin)); + rand("uniform"); + //rand('seed',0); + end +endfunction diff --git a/modules/cacsd/macros/st_ility.bin b/modules/cacsd/macros/st_ility.bin Binary files differnew file mode 100755 index 000000000..8883aa747 --- /dev/null +++ b/modules/cacsd/macros/st_ility.bin diff --git a/modules/cacsd/macros/st_ility.sci b/modules/cacsd/macros/st_ility.sci new file mode 100755 index 000000000..47943d959 --- /dev/null +++ b/modules/cacsd/macros/st_ility.sci @@ -0,0 +1,65 @@ +// 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 [n,nc,u,sl,v]=st_ility(sl,tol) + //stabilizability test + + [lhs,rhs]=argn(0) + if type(sl)==1 then + //[n,nc,u,A,B]=st_ility(A,B,tol) + if rhs==2 + sl=syslin("c",sl,tol,[]);rhs=1; + end + end + if typeof(sl)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space expected.\n"),"st_ility",1)) + end + + [a,b,c,d,x0,dom]=sl(2:7); + if dom==[] then + warning(msprintf(gettext("%s: Input argument #%d is assumed continuous time.\n"),"st_ility",1)); + dom="c"; + end + typ="c";if dom<>"c" then typ="d",end + [na,na]=size(a); + [nw,nb]=size(b); + if nb==0 then + b=zeros(na,1); + end + // controllable part + if rhs==1 then + [n,u,ind,V,a,b]=contr(a,b); + else + [n,u,ind,V,a,b]=contr(a,b,tol); + end; + if nb==0 then + b=[]; + end; + n=sum(n);nc=n; + if lhs==4 then c=c*u;x0=u'*x0;end + if n<>na then + //order evals uncont. part + nn=n+1:na; + [v,n1]=schur(a(nn,nn),part(typ,1)) + n=n+n1 + //new realization + if lhs>2 then + u(:,nn)=u(:,nn)*v + if lhs==4 then + a(:,nn)=a(:,nn)*v;a(nn,nn)=v'*a(nn,nn) + b(nn,:)=v'*b(nn,:) + c(:,nn)=c(:,nn)*v + x0(nn)=v'*x0(nn) + end; + end; + end; + // + if lhs==4 then sl=syslin(dom,a,b,c,d,x0),end + if lhs==5 then v=sl.B;sl=sl.A;end +endfunction diff --git a/modules/cacsd/macros/stabil.bin b/modules/cacsd/macros/stabil.bin Binary files differnew file mode 100755 index 000000000..273ae0bca --- /dev/null +++ b/modules/cacsd/macros/stabil.bin diff --git a/modules/cacsd/macros/stabil.sci b/modules/cacsd/macros/stabil.sci new file mode 100755 index 000000000..3dace87ce --- /dev/null +++ b/modules/cacsd/macros/stabil.sci @@ -0,0 +1,65 @@ +// 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 F=stabil(A,B,alfa) + // + //returns F such that A+B*F is stable if (A,B) is stabilizable. + //Assignable poles are set to alfa(1),alfa(2),... + //If (A,B) is not stabilizable a warning is displayed + //and assignable poles are set to alfa(1),alfa(2),... + // Default value for alfa is -1. + // + //K=stabil(Sys,alfa,Beta) returns K, a compensentor for Sys + //such that (A,B)-controllable eigenvalues are set to + //alfa and (C,A)-observable eigenvalues are set to Beta. + // All assignable closed loop poles (which are given by the + //eigenvalues of Aclosed=h_cl(Sys,K) are set to alfa(i)'s + //and Beta(j)'s. + // + //Example: + // Sys=ssrand(2,2,5,list('st',2,3,3)); + // A=Sys(2);B=Sys(3); F=stabil(A,B); + // spec(A) + //2 controllable modes 2 unstable uncontrollable modes + // and one stable uncontrollable mode + //spec(A+B*F) + //the two controllable modes are set to -1. + // + + [LHS,RHS]=argn(0) + if typeof(A)~="state-space" then + [ns,nc,U,sl]=st_ility(syslin("c",A,B,[])); + [nx,nx]=size(A);[nn,nu]=size(B); + if ns<nx then + warning(msprintf(gettext("%s: System not stabilizable (or detectable) => Stabilizing the stabilizable part.\n"),"stabil")); + end + if RHS==2 then + alfa=-ones(1,nx); + end + if prod(size(alfa))==1 then + alfa=alfa*ones(1,nx); + end + An=U'*A*U;Bn=U'*B; + k=size(alfa,"*"); + if k < nc then + alfa=[alfa,-ones(1,nc-k)]; + end + F=-ppol(An(1:nc,1:nc),Bn(1:nc,:),alfa(1:nc)); + F=[F,zeros(nu,nx-nc)]*U'; + else + //F=stabil(Sys,alfa,Beta); + Sys=A;[A1,B1,C1,D1]=abcd(Sys); + if RHS==1 then al=-1;be=-1;end + if RHS==2 then al=B;be=-1;end + if RHS==3 then al=B;be=alfa;end + F=stabil(A1,B1,al); + G=stabil(A1',C1',be);G=G'; + F=obscont(Sys,F,G); + end +endfunction diff --git a/modules/cacsd/macros/statgain.bin b/modules/cacsd/macros/statgain.bin Binary files differnew file mode 100755 index 000000000..3dad20c29 --- /dev/null +++ b/modules/cacsd/macros/statgain.bin diff --git a/modules/cacsd/macros/statgain.sci b/modules/cacsd/macros/statgain.sci new file mode 100755 index 000000000..5239bc40a --- /dev/null +++ b/modules/cacsd/macros/statgain.sci @@ -0,0 +1,38 @@ +// 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 st=statgain(sl) + + select typeof(sl) + case "rational" then + dom=sl("dt") + if dom=="c" then + st=freq(sl("num"),sl("den"),0) + else + st=freq(sl("num"),sl("den"),1) + end; + case "state-space" then + dom=sl.dt; + [m,p]=size(sl(2)); + if dom=="c" then + if rank(sl(2)) <> m then + error(msprintf(gettext("%s: Wrong values for input argument #%d: State matrix is singular.\n"),"statgain",1)), + end + st=sl(5)-sl(4)*inv(sl(2))*sl(3); + else + if rank(eye(m,m)-sl(2))<>m then + error(msprintf(gettext("%s: Wrong values for input argument #%d: State matrix - eye is singular.\n"),"statgain",1)) + end + st=sl(5)+sl(4)*inv(eye(m,m)-sl(2))*sl(3); + end; + else + error(97,1) + end + +endfunction diff --git a/modules/cacsd/macros/svplot.bin b/modules/cacsd/macros/svplot.bin Binary files differnew file mode 100755 index 000000000..8a990057a --- /dev/null +++ b/modules/cacsd/macros/svplot.bin diff --git a/modules/cacsd/macros/svplot.sci b/modules/cacsd/macros/svplot.sci new file mode 100755 index 000000000..1a2cc310d --- /dev/null +++ b/modules/cacsd/macros/svplot.sci @@ -0,0 +1,75 @@ +// 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 svm = svplot(Sl,w) + //svplot singular-value sigma-plot. + // svm = svplot(sl,w) computes for the linear dynamical system + // sl, the singular values of its transfer function matrix: + // -1 + // g(jw) = c(jw*i-a) b+d + // + // or + // -1 + // g(exp(jw)) = c(exp(jw)*i-a) b+d + // + // evaluated over the frequency range specified by w. + // sl is a sylin list (see syslin) representing the system + // [a,b,c,d] in state-space form. + // the i-th column of the output matrix svm contains the singular + // values of g(exp(jw)) for the i-th frequency value. + // svm = svplot(sl) is equivalent to + // svm = svplot(sl,logspace(-3,3)) (continuous) or + // svm = svplot(sl,logspace(-3,pi)) (discrete). + //! + + [a,b,c,d]=abcd(Sl); + // Reduce a to Hessenberg form + [q,a] = hess(a); b = q'*b; c = c*q; + // Compute the singular values of the frequency response + select Sl.dt + case [] + warning(msprintf(gettext("%s: Input argument #%d is assumed continuous time.\n"),"svplot",1)); + if argn(2) == 1 + w = logspace(-3,3); + end + nf = max(size(w)); nsv = min(size(d)); j = sqrt(-1); + svm(nsv,nf) = 0; + for i = 1:nf + svm(:,i) = svd(c*((j*w(i)*eye()-a)\b)+d); + end + case "c" + if argn(2) == 1 + w = logspace(-3,3); + end + nf = max(size(w)); nsv = min(size(d)); j = sqrt(-1); + svm(nsv,nf) = 0; + for i = 1:nf + svm(:,i) = svd(c*((j*w(i)*eye()-a)\b)+d); + end + case "d" + if argn(2) == 1 + w = logspace(-3,%pi); + end + nf = max(size(w)); nsv = min(size(d)); j = sqrt(-1); + svm(nsv,nf) = 0; + for i = 1:nf + svm(:,i) = svd(c*((exp(j*w(i))*eye()-a)\b)+d); + end + else T=Sl("dt"); + if argn(2) == 1 + w = logspace(-3,%pi); + end + nf = max(size(w)); nsv = min(size(d)); j = sqrt(-1); + svm(nsv,nf) = 0; + for i = 1:nf + svm(:,i) = svd(c*((exp(j*w(i)*T)*eye()-a)\b)+d); + end + + end +endfunction diff --git a/modules/cacsd/macros/sylv.bin b/modules/cacsd/macros/sylv.bin Binary files differnew file mode 100755 index 000000000..48d3471db --- /dev/null +++ b/modules/cacsd/macros/sylv.bin diff --git a/modules/cacsd/macros/sylv.sci b/modules/cacsd/macros/sylv.sci new file mode 100755 index 000000000..c1a51bc2b --- /dev/null +++ b/modules/cacsd/macros/sylv.sci @@ -0,0 +1,36 @@ +// 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 X = sylv(A,B,C,flag) + // solve A*X+X*B=C if flag=='c' or A*X*B+X=C if flag=='d' + if argn(2)<>4 then + error(msprintf(gettext("%s: Wrong number of input argument(s): %d expected.\n"),"sylv",4)) + end + if size(A,1)<> size(A,2) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A square matrix expected.\n"), "sylv", 1)); + end + if size(B,1)<> size(B,2) then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A square matrix expected.\n"), "sylv", 2)); + end + if size(C,1)<> size(A,1) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same number of rows expected.\n"),"sylv",1,3)) + end + if size(C,2)<> size(B,2) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same number of columns expected.\n"),"sylv",2,3)) + end + + if flag=="c" then + flag=[0 0 0], + elseif flag=="d" then + flag=[1 0 0], + else + error(msprintf(gettext("%s: Wrong value for input argument #%d: ""c"" or ""d"" expected.\n"), "sylv", 4)); + end + X=linmeq(1,A,B,C,flag) +endfunction diff --git a/modules/cacsd/macros/sysconv.bin b/modules/cacsd/macros/sysconv.bin Binary files differnew file mode 100755 index 000000000..bbbed5c93 --- /dev/null +++ b/modules/cacsd/macros/sysconv.bin diff --git a/modules/cacsd/macros/sysconv.sci b/modules/cacsd/macros/sysconv.sci new file mode 100755 index 000000000..923599519 --- /dev/null +++ b/modules/cacsd/macros/sysconv.sci @@ -0,0 +1,83 @@ +// 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 [s1,s2]=sysconv(s1,s2) + //Syntax : [s1,s2]=sysconv(s1,s2) + // + // Converts s1 and s2 into common representation in order that + // system interconnexion operations can be applied. + // The conversion rules in given in the following table. + // 'c' -> continuous time system + // 'd' -> discrete time system + // n -> sampled system with sampling period n + // [] -> system with undefined time domain + //For mixed systems s1 and s2 are put in state-space representation. + // + // + // + // s1\s2| 'c' | 'd' | n2 | [] | + // --------------------------------------------------------------- + // 'c' | nothing |uncompatible | c2e(s1,n2) | c(s2) | + // --------------------------------------------------------------- + // 'd' |uncompatible| nothing | e(s1,n2) | d(s2) | + // --------------------------------------------------------------- + // n1 | c2e(s2,n1) | e(s2,n1) | n1<>n2 uncomp | e(s2,n1) | + // | | | n1=n2 nothing | | + // --------------------------------------------------------------- + // [] | c(s1) | d(s1) | e(s1,n2) | nothing | + // --------------------------------------------------------------- + // + // Meaning: + //n1,n2 -> sampling period + //c2e(s,n) -> the continuous-time system s is transformed into + // a sampled system with sampling period n. + //c(s) -> conversion to continuous (time domain is 'c') + //d(s) -> conversion to discrete (time domain is 'd') + //e(s,n) -> conversion to samples system with period n + //! + + s11=s1(1);s21=s2(1); + if s11(1)<>s21(1) then // conversion ss<-->tf + if s11(1)=="r" then s1=tf2ss(s1),else s2=tf2ss(s2),end + s11=s1(1);s21=s2(1); + end; + + select s1("dt") + case "c" then t1=0 + case "d" then t1=1 + case [] then t1=3 + else t1=2 + end; + select s2("dt") + case "c" then t2=0 + case "d" then t2=1 + case [] then t2=3 + else t2=2 + end; + select t1+4*t2 + case 0 then, + case 1 then warning(msprintf(gettext("%s: time domains are not compatible.\n"), "sysconv")) + case 2 then s2=dscr(s2,s1("dt")) + case 3 then s1("dt")="c" + case 4 then warning(msprintf(gettext("%s: time domains are not compatible.\n"), "sysconv")) + case 5 then, + case 6 then s2("dt")=s1("dt") + case 7 then s1("dt")="d" + case 8 then s1=dscr(s1,s2("dt")) + case 9 then s1("dt")=s2("dt") + case 10 then + if s1("dt")<>s2("dt") then + warning(msprintf(gettext("%s: time domains are not compatible.\n"), "sysconv")) + end + case 11 then s1("dt")=s2("dt") + case 12 then s2("dt")="c" + case 13 then s2("dt")="d" + case 14 then s2("dt")=s1("dt") + end +endfunction diff --git a/modules/cacsd/macros/sysdiag.bin b/modules/cacsd/macros/sysdiag.bin Binary files differnew file mode 100755 index 000000000..c1cc1fbb9 --- /dev/null +++ b/modules/cacsd/macros/sysdiag.bin diff --git a/modules/cacsd/macros/sysdiag.sci b/modules/cacsd/macros/sysdiag.sci new file mode 100755 index 000000000..6292cfe5b --- /dev/null +++ b/modules/cacsd/macros/sysdiag.sci @@ -0,0 +1,36 @@ +// 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 r=sysdiag(varargin) + //Returns the block-diagonal system made with subsystems put in the main + //diagonal + // Syntax: + // r=sysdiag(a1,a2,...,an) + // + // ai : subsystems (i.e. gains, or linear systems in state-space or + // transfer form) + //Remark: + // At most 17 arguments... + //Example + // s=poly(0,'s') + // sysdiag(rand(2,2),1/(s+1),[1/(s-1);1/((s-2)*(s-3))]) + // sysdiag(tf2ss(1/s),1/(s+1),[1/(s-1);1/((s-2)*(s-3))]) + + + //! + r=varargin(1); + [m1,n1]=size(r); + for k=2:size(varargin) + ak=varargin(k) + [mk,nk]=size(ak); + r=[r,0*ones(m1,nk);0*ones(mk,n1),ak] + m1=m1+mk + n1=n1+nk + end +endfunction diff --git a/modules/cacsd/macros/sysfact.bin b/modules/cacsd/macros/sysfact.bin Binary files differnew file mode 100755 index 000000000..761f2cc50 --- /dev/null +++ b/modules/cacsd/macros/sysfact.bin diff --git a/modules/cacsd/macros/sysfact.sci b/modules/cacsd/macros/sysfact.sci new file mode 100755 index 000000000..d9a824129 --- /dev/null +++ b/modules/cacsd/macros/sysfact.sci @@ -0,0 +1,44 @@ +// 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 [S,Series]=sysfact(Sys,Gain,flag) + //For Sys=[A,B,C,D], + //if flag=='post' returns S = [A+B*Gain, B , Gain, I] + // and Series = minss(Sys*S) + //if flag=='pre' returns S=[A+Gain*C, Gain , C, I] + // and Series = minss(S*Sys) + if flag=="post" then + S=syslin(Sys("dt"),Sys("A")+Sys("B")*Gain, Sys("B"), Gain, eye(Gain*Sys("B"))); + //Series=minss(Sys*S); + Series= syslin("c",Sys("A")+Sys("B")*Gain, Sys("B"), Sys("C")+Sys("D")*Gain, Sys("D")); + end + if flag=="pre" then + S=syslin(Sys("dt"),Sys("A")+Gain*Sys("C"), Gain, Sys("C"), eye(Sys("C")*Gain)); + //Series=minss(S*Sys); + Series=syslin("c",Sys("A")+Gain*Sys("C"), Sys("B")+Gain*Sys("D"), Sys("C"), Sys("D")); + end + + + //Example: + //Sys=ssrand(3,2,4);Sys('D')=rand(3,2); + //S=sysfact(Sys,lqr(Sys),'post'); + //ww=minss(Sys*S); + //ss2tf(gtild(ww)*ww),Sys('D')'*Sys('D') + + //Syst=Sys'; + //S1=sysfact(Syst,lqe(Syst),'pre'); + //ww=minss(S1*Syst); + //ss2tf(ww*gtild(ww)),Syst('D')*Syst('D')' + + + //Sys=ssrand(2,3,4); + //[X,d,F,U,k,Z]=abinv(Sys); + //ss2tf(Sys*Z) + //ss2tf(Sys*sysfact(Sys,F,'post')*U) +endfunction diff --git a/modules/cacsd/macros/syslin.bin b/modules/cacsd/macros/syslin.bin Binary files differnew file mode 100755 index 000000000..b9a7994a3 --- /dev/null +++ b/modules/cacsd/macros/syslin.bin diff --git a/modules/cacsd/macros/syslin.sci b/modules/cacsd/macros/syslin.sci new file mode 100755 index 000000000..72e53e3ea --- /dev/null +++ b/modules/cacsd/macros/syslin.sci @@ -0,0 +1,131 @@ +// 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 [sl]=syslin(domain,a,b,c,d,x0) + + [lhs,rhs]=argn(0) + // + // check domain + select type(domain) + case 1 then //sampled system + if size(domain,"*")<=2 then + tp=domain + else + error(msprintf(gettext("%s: Wrong size for input argument #%d: A scalar expected.\n"),"syslin",1)) + end + z="z" + case 10 //continuous or discrete + if size(domain,"*")<>1 then + error(msprintf(gettext("%s: Wrong size for input argument #%d: A string expected.\n"),"syslin",1)) + end + + domain=part(domain,1) + select domain + case "c" then + z="s" + case "d" then + z="z" + else + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"), "syslin",1,"''c'',''d''")) + end; + else + error(msprintf(gettext("%s: Wrong type for input argument #%d: String, Scalar or empty matrix expected.\n"),"syslin",1)) + end; + //============================================================================ + if rhs==2 then //syslin(domaine,sys) + + if typeof(a)=="state-space" | typeof(a)=="rational" then + sl=a; + sl("dt")=domain + else + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"syslin",2)) + end + //============================================================================ + elseif rhs==3 then // syslin(domaine,num,den) + num=a;den=b + if type(num)>2 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Polynomial array expected.\n"),"syslin",2)) + end + if type(den)>2 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Polynomial array expected.\n"),"syslin",3)) + end + + if or(size(num)<>size(den)) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same sizes expected.\n"),"syslin",2,3)) + end + + if type(num)==2 & type(den)==2 then + if varn(num)<>varn(den) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same formal variable names expected.\n"),"syslin",2,3)) + end + end + if type(num)==1 then + num=num*poly(1,z,"c") + end + if type(den)==1 then + den=den*poly(1,z,"c") + end + + sl=rlist(varn(num,z),varn(den,z),domain) + //============================================================================ + elseif rhs>3 then // syslin(domaine,A,B,C [,D [X0]]) + if type(a)<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Array of floating point numbers expected.\n"),"syslin",2)) + end + [ma,na]=size(a); + if ma<>na then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Square matrix expected.\n"),"syslin",2)) + end + if type(b)<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Array of floating point numbers expected.\n"),"syslin",3)) + end + [mb,nb]=size(b); + if na<>mb&mb<>0 then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same row dimensions expected.\n"),"syslin",2,3)); + end + if type(c)<>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Array of floating point numbers expected.\n"),"syslin",4)) + end + [mc,nc]=size(c); + if na<>nc&nc<>0 then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),"syslin",2,4)); + end + if rhs<6 then + x0=0*ones(na,1) + else + if type(x0)>1 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Array of floating point numbers expected.\n"),"syslin",6)) + end + [mx,nx]=size(x0); + if mx<>na|nx<>min(na,1) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: "+.. + "number of elements of #%d must match the column dimension of #%d\n"),"syslin",6,1,6,1)); + end + end + if rhs<5 then + d=0*ones(mc,nb) + else + if type(d)>2 then + error(msprintf(gettext("%s: Wrong type for input argument #%d: Polynomial array expected.\n"),"syslin",5)) + end + [md,nd]=size(d); + if c*b<>[] then + if mc<>md then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same row dimensions expected.\n"),"syslin",2,5)); + end + if nb<>nd then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: Same column dimensions expected.\n"),"syslin",3,5)); + end + + end + end + sl=lsslist(a,b,c,d,x0,domain) + end + +endfunction diff --git a/modules/cacsd/macros/syssize.bin b/modules/cacsd/macros/syssize.bin Binary files differnew file mode 100755 index 000000000..a4c80142b --- /dev/null +++ b/modules/cacsd/macros/syssize.bin diff --git a/modules/cacsd/macros/syssize.sci b/modules/cacsd/macros/syssize.sci new file mode 100755 index 000000000..2ceb89e2b --- /dev/null +++ b/modules/cacsd/macros/syssize.sci @@ -0,0 +1,41 @@ +// 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 [io,s]=syssize(sys) + //Old stuff + // io=syssize(sys) + // [io,ns]=syssize(sys) + // + // sys : syslin list + // io : io=[nout,nin] + // nout: nb. outputs + // nin : nb. inputs + // s : nb states. + + select type(sys) + case 1 then + io=size(sys) + s=[] + case 16 then + sys1=sys(1) + select sys1(1) + case "lss" then + io=size(sys("D")), + [s,s]=size(sys("A")) + case "r" then + io=size(sys("den")) + [lhs,rhs]=argn(0); + if lhs==2 then sys=tf2ss(sys);[s,s]=size(sys("A")),end + else + error(97,1) + end + else + error(97,1), + end +endfunction diff --git a/modules/cacsd/macros/tf2des.bin b/modules/cacsd/macros/tf2des.bin Binary files differnew file mode 100755 index 000000000..3782dac52 --- /dev/null +++ b/modules/cacsd/macros/tf2des.bin diff --git a/modules/cacsd/macros/tf2des.sci b/modules/cacsd/macros/tf2des.sci new file mode 100755 index 000000000..dcee2bb77 --- /dev/null +++ b/modules/cacsd/macros/tf2des.sci @@ -0,0 +1,54 @@ +// 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 [S]=tf2des(G,flag) + //[S]=tf2des(G) + // Transfer function to descriptor form: S=list('d',A,B,C,D,E) + // E*dx=A*x+B*u + // y=C*x+D*u + // with flag="withD" a maximal rank D matrix is returned + //! + + [LHS,RHS]=argn(0); + if RHS==1 then flag=[];end + if RHS==2&flag<>"withD" then warning(msprintf(gettext("%s: Wrong value for input argument #%d: ''%s'' expected.\n"),"tf2des",2,"withD"));end + Num=G(2);Den=G(3); + %s=poly(0,varn(Den)); + [n,m]=size(Num); + pol=zeros(n,m);pro=pol; + // Pro = strictly proper part of G + // Pol = polynomial part of G. + for l=1:n, + for k=1:m, + denlk=Den(l,k); + [r,q]=pdiv(Num(l,k)+0*%s,denlk+0*%s); + pol(l,k)=q; + pro(l,k)=r/denlk; + end; + end; + + sp=tf2ss(pro); + D=zeros(Num); + + if flag=="withD" then + D=coeff(pol,0);pol=pol-D; + end; + spol=tf2ss(horner(pol,1/%s)/%s); + + [n1,n1]=size(sp(2)); + [n2,n2]=size(spol(2)); + A=[sp(2),0*ones(n1,n2); + 0*ones(n2,n1),eye(n2,n2)]; + E=[eye(n1,n1),0*ones(n1,n2); + 0*ones(n2,n1),spol(2)]; + B=[sp(3); + spol(3)]; + C=[sp(4),-spol(4)]; + S=tlist(["des","A","B","C","D","E"],A,B,C,D,E) +endfunction diff --git a/modules/cacsd/macros/tf2ss.bin b/modules/cacsd/macros/tf2ss.bin Binary files differnew file mode 100755 index 000000000..bb84f451a --- /dev/null +++ b/modules/cacsd/macros/tf2ss.bin diff --git a/modules/cacsd/macros/tf2ss.sci b/modules/cacsd/macros/tf2ss.sci new file mode 100755 index 000000000..c953185c7 --- /dev/null +++ b/modules/cacsd/macros/tf2ss.sci @@ -0,0 +1,84 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2010 - INRIA - Serge Steer +// +// 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 [sl]=tf2ss(h,tol) + // Transfer function to state-space. + //Syntax : sl=tf2ss(h [,tol]) + // h = transfer matrix + // sl = linear system in state-space representation (syslin list) + //! + + [lhs,rhs]=argn(0) + + if type(h)<=2 then + sl=syslin([],[],[],[],h); + return; + end + [num,den]=h(["num","den"]); + // + [nd,md]=size(den) + a=[];b=[];c=[];d=[];n1=0; // s=[] + for k=1:md + for l=1:nd + [r,q]=pdiv(num(l,k),den(l,k)); + dk(l)=q; + num(l,k)=r; + end + if nd<>1 then + [nk,pp]=cmndred(num(:,k),den(:,k)); + else + pp=den(k);nk=num(k); + end; + + slk=cont_frm(nk,pp); + [ak,bk,ck,dk1]=slk(2:5); + // [s sk] + [n2,m2]=size(bk); + if n2<>0 then + a(n1+1:n1+n2,n1+1:n1+n2)=ak; + b(n1+1:n1+n2,k)=bk; + c=[c ck]; + n1=n1+n2; + else + if n1<>0 then b(n1,k)=0;end + end; + d=[d dk]; + end; + + if degree(d)==0 then d=coeff(d),end + + if n1<>0 then + nrmb=norm(b,1); + nrmc=norm(c,1); + fact=sqrt(nrmc*nrmb); + b=b*fact/nrmb; + c=c*fact/nrmc; + atmp=a; + [a,u]=balanc(a); + //next lines commented out to fix bug 3796 + // if rcond(u)< %eps*n1*n1*100 + // nn=size(a,1);u=eye(nn,nn);a=atmp; + // end + + //apply transformation u without matrix inversion + [k,l]=find(u<>0) //get the permutation + u=u(k,l);c=c(:,k)*u; b=diag(1 ./diag(u))*b(k,:); + + if rhs<2 then + [no,u]=contr(a',c',%eps); + else + [no,u]=contr(a',c',tol); + end + u=u(:,1:no); + a=u'*a*u;b=u'*b;c=c*u; + sl=syslin(h("dt"),a,b,c,d); + else + sl=syslin(h("dt"),[],[],[],d) + end +endfunction diff --git a/modules/cacsd/macros/time_id.bin b/modules/cacsd/macros/time_id.bin Binary files differnew file mode 100755 index 000000000..8eb4cb799 --- /dev/null +++ b/modules/cacsd/macros/time_id.bin diff --git a/modules/cacsd/macros/time_id.sci b/modules/cacsd/macros/time_id.sci new file mode 100755 index 000000000..c0ef70bc1 --- /dev/null +++ b/modules/cacsd/macros/time_id.sci @@ -0,0 +1,49 @@ +// 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 [h,err]=time_id(n,u,y) + + [lhs,rhs]=argn(0) + y=y(:) + npt=size(y,"*"); + select type(u) + case 1 then + u=u(:) + case 10 then + select part(u,1) + case "i" then + u=eye(npt,1) + case "s" then + u=ones(npt,1) + else + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),"time_id",2,"""i"",""s""")) + end + else + error(msprintf(gettext("%s: Wrong value for input argument #%d: Must be in the set {%s}.\n"),"time_id",2,"""i"",""s""")) + end + if y(1)==0 then // strictly proper case + m(npt-1,2*n)=0; + for k=1:n,m(k:npt-1,[k k+n])=[-y(1:npt-k) u(1:npt-k)];end + coef=m\y(2:npt); + num=poly(coef(2*n:-1:n+1),"z","c"); + den=poly([coef(n:-1:1);1],"z","c"); + else + m(npt,2*n+2)=0; + for k=1:n+1,m(k:npt,[k k+n+1])=[-y(1:npt-k+1) u(1:npt-k+1)];end + coef=-m(:,2:$)\m(:,1) + num=poly(coef(2*n+1:-1:n+1),"z","c"); + den=poly([coef(n:-1:1);1],"z","c"); + end + + h=syslin("d",num,den) + + if lhs==2 then + err=norm(y-rtitr(num,den,u')',2) + end +endfunction diff --git a/modules/cacsd/macros/trfmod.bin b/modules/cacsd/macros/trfmod.bin Binary files differnew file mode 100755 index 000000000..fe5a6d722 --- /dev/null +++ b/modules/cacsd/macros/trfmod.bin diff --git a/modules/cacsd/macros/trfmod.sci b/modules/cacsd/macros/trfmod.sci new file mode 100755 index 000000000..9c8da5dea --- /dev/null +++ b/modules/cacsd/macros/trfmod.sci @@ -0,0 +1,179 @@ +// 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 h=trfmod(h,job) + // hm=trfmod(h [,job]) + // To visualize the pole-zero structure of a SISO transfer function h + // job='p' : visualization of polynomials (default) + // job='f' : visualization of natural frequencies and damping + // + //! + select typeof(h) + case "rational" then + if size(h("num"))<>[1 1] then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Single input, single output system expected.\n"),"trfmod",1)) + end + flag="r" + case "state-space" then + if size(h("D"))<>[1 1] then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Single input, single output system expected.\n"),"trfmod",1)) + end + flag="lss" + den=real(poly(h("A"),"s")) + na=degree(den) + c=h(4) + [m,i]=max(abs(c)) + ci=c(i) + t=eye(h(2))*ci;t(i,:)=[-c(1:i-1), 1, -c(i+1:na)] + al=h(2)*t; + t=eye(h(2))/ci;t(i,:)=[c(1:i-1)/ci, 1, c(i+1:na)/ci] + al=t*al;ai=al(:,i), + b=t*h(3) + al(:,i)=ai+b + num=-(real(poly(al,"s"))-den)*ci + h=syslin(h(7),num+h(5)*den,den); + else + error(msprintf(gettext("%s: Wrong type for input argument #%d: Linear state space or a transfer function expected.\n"),"trfmod",1)) + end + + + // + ft = format(); + format("v", 15); + + [lhs,rhs]=argn(0) + if rhs==1 then job="p",end + // + if type(h("num"))==1 then h("num")=poly(h("num"),varn(h("den")),"c"),end + if type(h("den"))==1 then h("den")=poly(h("den"),varn(h("num")),"c"),end + + var=varn(h("num")),nv=length(var); + while part(var,nv)==" " then nv=nv-1,end;var=part(var,1:nv); + + fnum=polfact(h("num")) + fden=polfact(h("den")) + g=coeff(fnum(1))/coeff(fden(1)) + nn=prod(size(fnum)) + nd=prod(size(fden)) + // + num=[] + for in=2:nn + p=fnum(in) + if job=="p" then + num=[num;pol2str(p)] + else + if degree(p)==2 then + p=coeff(p) + omeg=sqrt(p(1)) + xsi=p(2)/(2*omeg) + num=[num;string(omeg)+" "+string(xsi)] + else + num=[num;string(-coeff(p,0))] + end + end + end + // + den=[]; + for id=2:nd + p=fden(id) + if job=="p" then + den=[den;pol2str(p)] + else + if degree(p)==2 then + p=coeff(p) + omeg=sqrt(p(1)) + xsi=p(2)/(2*omeg) + den=[den;string(omeg)+" "+string(xsi)] + else + den=[den;string(-coeff(p,0))] + end + end + end + + txt=[_("Gain :");string(g);_("Numerator :");num;_("Denominator :");den] + + id=[] + if job=="p" then + tit=[gettext("Irreducible Factors of transfer function (click below)")] + else + tit=[gettext("Irreducible Factors of transfer function natural frequency and damping factor (click below)")] + end + while id==[] then + t=x_dialog(tit,txt) + id=find(t==_("Denominator :")) + end + txt=t; + + tgain=txt(2) + tnum=txt(4:id-1) + tden=txt(id+1:prod(size(txt))) + execstr(var+"=poly(0,''"+var+"'')") + num=1 + for in=1:prod(size(tnum)) + txt=tnum(in) + if length(txt)==0 then txt=" ",end + if job=="p" then + t=" "; + for k=1:length(txt), + tk=part(txt,k), + if tk<>" " then t=t+tk,end + end + f=1;if t<>" " then f=evstr(t),end + else + if txt==part(" ",1:length(txt)) then + f=1 + else + f=evstr(txt) + select prod(size(f)) + case 1 then + f=poly(f,var) + case 2 then + f=poly([f(1)*f(1), 2*f(1)*f(2),1],var,"c") + else + error(msprintf(gettext("%s: Incorrect answer.\n"),"trfmod")) + end + end + end + num=num*f + end + // + den=1 + for id=1:prod(size(tden)) + txt=tden(id); + if length(txt)==0 then txt=" ",end + if job=="p" then + t=" "; + for k=1:length(txt), + tk=part(txt,k), + if tk<>" " then t=t+tk,end + end + f=1;if t<>" " then f=evstr(t),end + else + if txt==part(" ",1:length(txt)) then + f=1 + else + f=evstr(txt) + select prod(size(f)) + case 1 then + f=poly(f,var) + case 2 then + f=poly([f(1)*f(1), 2*f(1)*f(2),1],var,"c") + else + error(msprintf(gettext("%s: Incorrect answer.\n"),"trfmod")) + end + end + end + den=den*f + end + x=evstr(tgain)/coeff(den,degree(den)) + h("num")=num*x + h("den")=den/coeff(den,degree(den)) + format(ft(2),ft(1)); + if flag=="lss" then h=tf2ss(h),end +endfunction diff --git a/modules/cacsd/macros/trianfml.bin b/modules/cacsd/macros/trianfml.bin Binary files differnew file mode 100755 index 000000000..b8b197587 --- /dev/null +++ b/modules/cacsd/macros/trianfml.bin diff --git a/modules/cacsd/macros/trianfml.sci b/modules/cacsd/macros/trianfml.sci new file mode 100755 index 000000000..9aa211851 --- /dev/null +++ b/modules/cacsd/macros/trianfml.sci @@ -0,0 +1,60 @@ +// 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 [f,sexp]=trianfml(f,sexp) + // [f [,sexp]]=trianfml(f [,sexp]) Triangularization of the symbolic matrix + // f ; Triangularization is performed by elementary row operations; + // sexp is a set of common expressions stored by the algorithm. + //! + // + + [lhs,rhs]=argn(0) + [mf,nf]=size(f) + f_tra=f + // + // row loop + // ------------------------------ + // + for nli=1:mf + // + [mf_tra,nf_tra]=size(f_tra) + //recherche du pivot dans la premiere colonne + c1=f_tra(:,1); + lc=length(c1);[lc,klc]=gsort(lc); + pivot="0";l=mf_tra+1; + while (pivot=="0"&l>1), + l=l-1; + if c1(klc(l))<>"0" then pivot=c1(klc(l)),end, + end + if pivot<>"0" then + l=klc(l) + // + if l<>1 then f_tra([1 l],:)=f_tra([l 1],:);c1([1 l])=c1([l 1]);end + // + for k=2:mf_tra, + if c1(k)<>"0" then + f_tra(k,:)=cmb_lin(pivot,f_tra(k,:),c1(k),f_tra(1,:)) + f_tra(k,1)="0" + if rhs==2 then + ns=prod(size(sexp)), + for kl=2:nf_tra + if length(f_tra(k,kl))>20 then + ns=ns+1 + sexp(ns)=f_tra(k,kl) + f_tra(k,kl)="%("+string(ns)+")" + end; + end; + end; + end; + end; + f(mf-mf_tra+1:mf,nf-nf_tra+1:nf)=f_tra + f_tra=f_tra(2:mf_tra,2:nf_tra) + end + end; +endfunction diff --git a/modules/cacsd/macros/trisolve.bin b/modules/cacsd/macros/trisolve.bin Binary files differnew file mode 100755 index 000000000..7e89a901f --- /dev/null +++ b/modules/cacsd/macros/trisolve.bin diff --git a/modules/cacsd/macros/trisolve.sci b/modules/cacsd/macros/trisolve.sci new file mode 100755 index 000000000..a1d039646 --- /dev/null +++ b/modules/cacsd/macros/trisolve.sci @@ -0,0 +1,47 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - F. Delebecque , Serge STEER +// +// 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 [b,sexp]=trisolve(a,b,sexp) + //[x [,sexp]] = trisolve(A,b [,sexp]) symbolically solves A*x =b + // when A and b are matrices of character strings, A being assumed to be + // upper triangular. + //sexp : vector of common subexpressions in A, b and x. + //! + + [lhs,rhs]=argn(0) + [n0,m]=size(b) + if rhs==2 then + for n=n0:-1:1 + pivot=a(n,n) + for k=1:m,b(n,k)=ldivf(pivot,"("+b(n,k)+")"),end + if n==1 then return,end + for l=1:n-1 + for k=1:m, + b(l,k)=addf(b(l,k),mulf(mulf("-1",a(l,n)),b(n,k))) + end + end + end + else + ns=prod(size(sexp)) + for n=n0:-1:1 + pivot=a(n,n) + for k=1:m, + ns=ns+1 + sexp(ns)=ldivf(pivot,"("+b(n,k)+")") + b(n,k)="%("+string(ns)+")"; + end + if n==1 then return,end + for l=1:n-1 + for k=1:m, + b(l,k)=addf(b(l,k),mulf(mulf("-1",a(l,n)),b(n,k))) + end + end + end + end +endfunction diff --git a/modules/cacsd/macros/trzeros.bin b/modules/cacsd/macros/trzeros.bin Binary files differnew file mode 100755 index 000000000..23d7073bd --- /dev/null +++ b/modules/cacsd/macros/trzeros.bin diff --git a/modules/cacsd/macros/trzeros.sci b/modules/cacsd/macros/trzeros.sci new file mode 100755 index 000000000..d201209a5 --- /dev/null +++ b/modules/cacsd/macros/trzeros.sci @@ -0,0 +1,102 @@ +// 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 [nt,dt,rk]=trzeros(Sl) + //Transmission zeros of Sl = nt./dt + // Syntax : [nt,dt]=trzeros(Sl) + //! + + [LHS,RHS]=argn(0); + sltyp=typeof(Sl) + + if sltyp == "polynomial" then + D=Sl; + [m,n]=size(D); + if m<>n then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Square matrix expected.\n"),"trzeros",1)); + return; + end + chis=det(D);nt=roots(chis);dt=ones(nt); + if LHS==1 then + nt=nt./dt;dt=[];rk=[]; + end + return; + end + + if sltyp == "rational" then + if size(Sl)==1 then + nt=roots(Sl("num"));dt=[];rk=1; + return; + end + Sl=tf2ss(Sl); + end + + if typeof(Sl)<>"state-space" then + error(msprintf(gettext("%s: Wrong type for input argument #%d: A linear dynamical system or a polynomial expected.\n"),"trzeros",1)) + end + + //Sl=minss(Sl); + [A,B,C,D]=Sl(2:5); + if type(D)==2 then + [m,n]=size(D); + if m<>n then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Square system expected.\n"),"trzeros",1)); + end + chis=det(systmat(Sl));nt=roots(chis);dt=ones(nt); + if LHS==1 then nt=nt./dt;dt=[];rk=[];end + return; + end + + if size(A,"*")==0 then + if type(D)==1 then nt=[];dt=[];return;end; + if type(D)==2 then + [m,n]=size(D); + if m<>n then + error(msprintf(gettext("%s: Wrong size for input argument #%d: Square system expected.\n"),"trzeros",1)); + end + chis=det(D);nt=roots(chis);dt=ones(nt); + if LHS==1 then nt=nt./dt;dt=[];rk=[];end + return; + end; + end; + [ld,kd]=size(D); + if norm(D,1)<sqrt(%eps)|ld==kd then + [nt,dt,rk]=tr_zer(A,B,C,D); + if norm(dt,1) > 1.d-10 then + if LHS==1 then nt=nt./dt;dt=[];rk=[];end + return; + end + end + if ld < kd & norm(D*pinv(D)-eye(),1)< 1.d-10 + //nt=spec(A-B*pinv(D)*C);dt=ones(nt); + [nt,dt]=tr_zer(A,B,C,D); + rk=ld; + if LHS==1 then nt=nt./dt;end; + return; + end + if ld > kd & norm(pinv(D)*D-eye(),1)< 1.d-10 + //nt=spec(A-B*pinv(D)*C);dt=ones(nt); + [nt,dt]=tr_zer(A,B,C,D); + rk=kd; + if norm(dt,1) > 1.d-10 then + if LHS==1 then nt=nt./dt;dt=[];rk=[];end;return; + end + end + //warning('Trzeros:non-square system with D non zero and not full') + //By kronecker form + s=poly(0,"s"); + syst_matrix=systmat(Sl); //form system matrix + [Q,Z,Qd,Zd,numbeps,numbeta]=kroneck(syst_matrix); + ix=Qd(1)+Qd(2)+1:Qd(1)+Qd(2)+Qd(3); + iy=Zd(1)+Zd(2)+1:Zd(1)+Zd(2)+Zd(3); + finitepencil=Q(ix,:)*syst_matrix*Z(:,iy); + [E,A]=pen2ea(finitepencil); + [nt,dt]=spec(A,E);rk=[]; + if LHS==1 then nt=nt./dt;dt=[];rk=[];end; +endfunction diff --git a/modules/cacsd/macros/ui_observer.bin b/modules/cacsd/macros/ui_observer.bin Binary files differnew file mode 100755 index 000000000..23bc14c6f --- /dev/null +++ b/modules/cacsd/macros/ui_observer.bin diff --git a/modules/cacsd/macros/ui_observer.sci b/modules/cacsd/macros/ui_observer.sci new file mode 100755 index 000000000..2aa9fa401 --- /dev/null +++ b/modules/cacsd/macros/ui_observer.sci @@ -0,0 +1,119 @@ +// 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 [UIobs,J,N]=ui_observer(Sys,reject,C1,D1,flag,Alfa,Beta) + // ------------Unknown input observer------------------ + // Sys: (w,u) --> y = (A,B,C2,D2) syslin linear system with two inputs + // w and u, w being the unknown input. + // The matrices B and D2 of Sys are (implicitly) partitioned as: + // B=[B1,B2] and D2=[D21,D22] with B1=B(:,reject) and D21=D2(:,reject) + // where reject = indices of unknown inputs. + // The matrices C1 and D1 define + // z = C1 x + D1 (w,u) = the to-be-estimated output + // the matrix D1 is (implicitly) partitioned as + // D1=[D11,D12] with D11=D(:,reject) + // + // The data (Sys, reject,C1, D1) define a 2-input 2-output system: + // + // xdot = A x + B1 w + B2 u + // z = C1 x + D11 w + D12 u + // y = C2 x + D21 w + D22 u + // + // An observer (u,y) --> zhat is looked for the output z. + // flag='ge' no stability constraints + // ='st' stable observer (default) + // ='pp' observer with pole placement + // Alfa,Beta = desired location of closed loop poles (default -1, -2) + // UIobs = linear system (u,y) --> zhat such that: + // The transfer function: (w,u) --> z equals the composed transfer function: + // [0,I; UIobs + // Sys] + // (w,u) -----> (u,y) -----> zhat + // i.e. transfer function of system {A,B,C1,D1} equals + // transfer function UIobs*[0,I; Sys] + // J=y-output to x-state injection + // N=y-output to z-estimated output injection + // Example: + //A=diag([3,-3,7,4,-4,8]); + //B=[eye(3,3);zeros(3,3)]; + //C=[0,0,1,2,3,4;0,0,0,0,0,1]; + //D=[1,2,3;0,0,0]; + //rand('seed',0);w=ss2ss(syslin('c',A,B,C,D),rand(6,6)); + //[A,B,C,D]=abcd(w); + //B=[B,matrix(1:18,6,3)];D=[D,matrix(-(1:6),2,3)]; + //reject=1:3; + //Sys=syslin('c',A,B,C,D); + //N1=[-2,-3];C1=-N1*C;D1=-N1*D; + //nw=length(reject);nu=size(Sys('B'),2)-nw; + //ny=size(Sys('C'),1);nz=size(C1,1); + //[UIobs,J,N]=ui_observer(Sys,reject,C1,D1); + // + //W=[zeros(nu,nw),eye(nu,nu);Sys];UIobsW=UIobs*W; + //(w,u) --> z=UIobs*[0,I;Sys](w,u) + //clean(ss2tf(UIobsW)); + //wu_to_z=syslin('c',A,B,C1,D1);clean(ss2tf(wu_to_z)); + //clean(ss2tf(wu_to_z)-ss2tf(UIobsW),1.d-7) + //2nd ex: nx=2;ny=3;nwu=2;Sys=ssrand(ny,nwu,nx); + // C1=rand(1,nx);D1=[0,1]; + // UIobs=ui_observer(Sys,1,C1,D1); + [LHS,RHS]=argn(0); + if RHS==6 then Beta=-1;end + if RHS==5 then Beta=-1;Alfa=-1;end + if RHS==4 then Beta=-1;Alfa=-1;flag="st";end + if RHS==3 then Beta=-1;Alfa=-1;flag="st";D1=[];end + if size(C1,2) ~= size(Sys("A"),1) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: "+.. + "state dimension of #%d must be equal to the column dimension of #%d.\n"),.. + "ui_observer",1,3,1,3)) + end + if size(D1,2) ~= size(Sys("B"),2) then + error(msprintf(gettext("%s: Incompatible input arguments #%d and #%d: "+.. + "input dimension of #%d must be equal to the column dimension of #%d.\n"),.. + "ui_observer",4,1,4,1)) + end + not_reject=1:size(Sys,"c");not_reject(reject)=[]; + Sys1=Sys(:,reject); //A,B1,C2,D21 + [X,dims,J,Y,k,Z]=cainv(Sys1,Alfa,Beta,flag); + Sys_new=ss2ss(Sys,X); + ns=dims(3);Jnew=X'*J;J2=Jnew(ns+1:$,:); + [Anew,Bnew,Cnew,Dnew]=abcd(Sys_new); + A22=Anew(ns+1:$,ns+1:$);C22=Cnew(:,ns+1:$); + B22=Bnew(ns+1:$,not_reject);D22=Dnew(:,not_reject); + Sys22=syslin(Sys("dt"),A22,B22,C22,D22); + UIobs=observer(Sys22,J2); + // + C1new=C1*X; + D11=D1(:,reject);D21=Dnew(:,reject); + C11=C1new(:,1:ns);C21=Cnew(:,1:ns); + //N s.t. [I,N]*[C11 D11;C21 D21]=[0,0] + N=lowlevel(); + mprintf(gettext("%s: Residual norm = %g\n"),"ui_observer",norm([eye(size(N,1),size(N,1)),N]*[C11,D11;C21,D21])); + D12=D1(:,not_reject);C12=C1new(:,ns+1:$); + UIobs("C")=[C12+N*C22];UIobs("D")=[D12+N*D22,-N]; + +endfunction + +function N=lowlevel() + ww=[C11 D11;C21 D21]; + [xx,dd]=rowcomp(ww); + K=xx(dd+1:$,:); + colN=size(C21,1);rowN=size(C11,1); + if size(K,1) > rowN then K=K(1:rowN,:);end + Kleft=K(:,1:size(K,1)) + if size(Kleft,"*")==1 & abs(Kleft) <1.d-8 then + N=[]; + error(msprintf(gettext("%s: Bad conditionning.\n"),"ui_observer")); + end + if rcond(Kleft) <= 1.d-10 then + warning(msprintf(gettext("%s: Bad conditionning.\n"),"ui_observer")); + K1=pinv(Kleft)*K;N=K1(:,size(K,1)+1:$);return + end + K1=inv(Kleft)*K; //test conditioning here! + N=K1(:,size(K,1)+1:$) +endfunction diff --git a/modules/cacsd/macros/unobs.bin b/modules/cacsd/macros/unobs.bin Binary files differnew file mode 100755 index 000000000..daa750f18 --- /dev/null +++ b/modules/cacsd/macros/unobs.bin diff --git a/modules/cacsd/macros/unobs.sci b/modules/cacsd/macros/unobs.sci new file mode 100755 index 000000000..ec888f8bd --- /dev/null +++ b/modules/cacsd/macros/unobs.sci @@ -0,0 +1,43 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) INRIA - +// Copyright (C) 2012 - Scilab Enterprises - Cedric Delamarrre +// +// 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 [dim,x]=unobs(A,C,tol) + // n first columns of x span the unobservable + // subspace of (A,C): + // dim + // [*,*] + // X'*A*X = [0,*] + // + // C*X = [0,*] + // Copyright INRIA + + [lhs,rhs]=argn(0); + + if rhs < 2 + error(msprintf(gettext("%s: Wrong number of input argument: %d to %d expected."),"unobs", 2, 3)); + end + + if typeof(A) <> "constant" | ~isreal(A) + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real matrix expected."),"unobs",1)); + end + + if typeof(C) <> "constant" | ~isreal(C) + error(msprintf(gettext("%s: Wrong type for input argument #%d: A real matrix expected."),"unobs",2)); + end + + if rhs == 2 + tol=1.d-10*norm([A;C],1); + end + + [p,p]=size(A); + [n,w]=contr(A',C',tol); + x=[w(:,n+1:p),w(:,1:n)]; + dim=p-n; +endfunction diff --git a/modules/cacsd/macros/zeropen.bin b/modules/cacsd/macros/zeropen.bin Binary files differnew file mode 100755 index 000000000..5e1d5e4e6 --- /dev/null +++ b/modules/cacsd/macros/zeropen.bin diff --git a/modules/cacsd/macros/zeropen.sci b/modules/cacsd/macros/zeropen.sci new file mode 100755 index 000000000..098009ae3 --- /dev/null +++ b/modules/cacsd/macros/zeropen.sci @@ -0,0 +1,23 @@ +// 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 [Z,U]=zeropen(Sl) + //Z = sE - F = zero pencil of Sl=[A,B,C,D] + // With U row compression of [B;D] i.e, U*[B;D]=[0;*]; + //U*[-sI+A |B; [ Z |0; + // C |D] = [ * |*] + + s=poly(0,"s"); + [A,B,C,D]=abcd(Sl); + BD=[B;D]; + [n,m]=size(BD); + [U,rk]=rowcomp(BD);U=[U(rk+1:n,:);U(1:rk,:)]; + W=U*([-s*eye()+A;C]) + Z=W(1:n-rk,:); +endfunction diff --git a/modules/cacsd/macros/zgrid.bin b/modules/cacsd/macros/zgrid.bin Binary files differnew file mode 100755 index 000000000..a80a3c2f9 --- /dev/null +++ b/modules/cacsd/macros/zgrid.bin diff --git a/modules/cacsd/macros/zgrid.sci b/modules/cacsd/macros/zgrid.sci new file mode 100755 index 000000000..cab7706fa --- /dev/null +++ b/modules/cacsd/macros/zgrid.sci @@ -0,0 +1,170 @@ +// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab +// Copyright (C) 2005 - INRIA - Farid Belahcene +// Copyright (C) 2010 - INRIA - Serge STEER +// 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 []=zgrid(varargin) + // zgrid(["new",] [,Z,Wn [,colors]]) + // zgrid(Z,Wn [,"new"] [,colors]) + defaultcolors=[-1 -1]; + defaultbounds=[-1,-1;1,1]; + rhs=argn(2) + new=%f + if rhs>=1 then + if type(varargin(1))==10 then + if varargin(1)<>"new" then + error(msprintf(_("%s: Wrong value for input argument #%d: ''%s'' expected.\n"),"zgrid",1,"new")) + end + varargin(1)=null() + rhs=rhs-1 + new=%t + end + end + if rhs>=3 then + if type(varargin(3))==10 then + if varargin(3)<>"new" then + error(msprintf(_("%s: Wrong value for input argument #%d: ''%s'' expected.\n"),"zgrid",3,"new")) + end + varargin(3)=null() + rhs=rhs-1 + new=%t + end + end + + defaultwn=0:0.1:1; + defaultzeta=0:0.1:1; + + select rhs + case 0 then //zgrid() or zgrid("new") + wn=defaultwn + zeta = defaultzeta + colors = defaultcolors + case 1 then + zeta = varargin(1) + if type(zeta)<>1|~isreal(zeta) then + error(msprintf(_("%s: Wrong type for input argument #%d : real floating point array expected\n"),"zgrid",1)); + end + wn=defaultwn + colors = defaultcolors + case 2 then + zeta = varargin(1) + if type(zeta)<>1|~isreal(zeta) then + error(msprintf(_("%s: Wrong type for input argument #%d : real floating point array expected\n"),"zgrid",1)); + end + wn = varargin(2) + if type(wn)<>1|~isreal(wn) then + error(msprintf("%s: Wrong type for input argument #%d : real floating point array expected\n"),"zgrid",2); + end + colors = defaultcolors + case 3 then + zeta = varargin(1) + if type(zeta)<>1|~isreal(zeta) then + error(msprintf(_("%s: Wrong type for input argument #%d : real floating point array expected\n"),"zgrid",1)); + end + wn = varargin(2) + if type(wn)<>1|~isreal(wn) then + error(msprintf(_("%s: Wrong type for input argument #%d : real floating point array expected\n"),"zgrid",2)); + end + colors = varargin(3); + if type(colors)<>1|~isreal(colors) then + error(msprintf(_("%s: Wrong type for input argument #%d : real floating point array expected\n"),"zgrid",3)); + end + if size(colors,"*")==1 then colors=colors*ones(1,2),end + end + wn=wn(wn>0&wn<=1); + zeta=zeta(zeta>=0&zeta<=1); + + fig = gcf(); + immediate_drawing=fig.immediate_drawing; + fig.immediate_drawing = "off"; + axes=gca();drawlater(); show_window(); + if new&axes.children<>[] then + delete(axes.children) + end + nc=size(axes.children,"*") + if nc==0 then + axes.data_bounds=defaultbounds + axes.axes_visible="on"; + axes.box="on"; + axes.title.text=msprintf(_("loci with constant damping and constant natural frequency\nin discrete plane")) + axes.x_label.text=_("Real Axis") + axes.y_label.text=_("Imaginary Axis") + end + axes.fractional_font="on" + axes.font_size=0.5 + chart_handles=[] + + // 2 2 + //roots of s + 2*zeta*wn*s +wn + //given by : wn*(-zeta+-%i*sqrt(1-sxi*zeta)) + + raci=((0:0.05:1)*%pi)'*(-zeta+%i*sqrt(ones(zeta)-zeta.*zeta)) + // continuous --> discrete + raci=exp(raci);[mr,nr]=size(raci); + for l=1:nr, + r=[raci(:,l);conj(raci($:-1:1,l))] + xpoly(real(r),imag(r)) + ec=gce(); + ec.display_function = "formatZgridDampingTip"; + ec.display_function_data = zeta(l); + ec.foreground=colors(1), + ec.line_style=7; + ec.clip_state="clipgrf"; + + xstring(real(raci(mr-10,l)),-imag(raci(mr-10,l))," "+string(zeta(l)),0,0); + es=gce(); + es.font_foreground=colors(1), + es.clip_state="clipgrf"; + chart_handles=[glue([es ec]) chart_handles] + end; + + e_itheta=exp(%i*(%pi/2:0.05:%pi)') + zw=exp(e_itheta*(wn*%pi));[mz,nz]=size(zw) + + for l=1:nz, + z=[zw(:,l);zw($:-1:1,l)]; + xpoly(real(z),imag(z)) + ec=gce(); + ec.display_function = "formatZgridFreqTip"; + ec.display_function_data = wn(l); + ec.foreground=colors(2), + ec.line_style=7; + ec.clip_state="clipgrf"; + str=msprintf("%0.3gπ/dt",wn(l)) + xstring(real(zw(1,l)),imag(zw(1,l)),str,0,0); + es=gce(); + es.font_foreground=colors(2), + es.clip_state="clipgrf"; + chart_handles=[glue([es ec]) chart_handles] + xpoly(real(z),-imag(z)) + ec=gce(); + ec.display_function = "formatZgridFreqTip"; + ec.display_function_data = wn(l); + ec.foreground=colors(2), + ec.line_style=7; + ec.clip_state="clipgrf"; + + xstring(real(zw(1,l)),-imag(zw(1,l)),str,0,0); + es=gce(); + es.font_foreground=colors(2), + es.clip_state="clipgrf"; + chart_handles=[glue([es ec]) chart_handles] + end; + chart_handles=glue(chart_handles) + //reorder axes children to make chart drawn before the previously + // drawn curves if any + for k=1:nc + swap_handles(axes.children(k),axes.children(k+1)) + end + + if nc==0 then + axes.data_bounds=defaultbounds + end + + fig.immediate_drawing = immediate_drawing; + +endfunction |