home *** CD-ROM | disk | FTP | other *** search
- //---------------------------------------------------------------------------------
- //
- // tzero
- //
- // Syntax: A=tzero(a,b,c,d)
- //
- // This routine computes the transmission zeros of the state-space system
- // defined by (a,b,c,d). Calling the routine as Z=tzero(a,b,c,d) returns the
- // transmission zeros of state-space system (either continuous or discrete)
- // given by,
- // . .
- // x = Ax + Bu or x[n+1] = Ax[n] + Bu[n]
- // y = Cx + Du y[n] = Cx[n] + Du[n]
- //
- // If the system is SISO, then the transfer funtion gains will also be
- // returned (as part of the return list).
- //
- // It extracts from the system matrix of a state-space system [ A B C D ] a
- // regular pencil [ Lambda*Bf - Af ] which has the NU Invariant Zeros of the
- // system as Generalized Eigenvalues.
- //
- // REFERENCE: Ported to RLaB from the FORTRAN Code contained in:
- // Emami-Naeini, A., and Van Dooren, A., "Computation of Zeros of Linear
- // Multivaraible Systems," Automatica, Vol. 18, No. 4, April 1982, pp. 415-430.
- //
- // The transmission zero calculation can be tested by checking that the
- // matrix: [A B;C D]-lambda*[I 0; 0 0] is rank deficient, where lambda
- // is an element of Z.
- //
- // The results are returned in a list:
- //
- // A.z= z (transmission zeros)
- // A.gain = gain (transfer function gain if SISO)
- //
- // Copyright (C), by Jeffrey B. Layton, 1994
- // Version JBL 931205
- //---------------------------------------------------------------------------------
-
- rfile isempty
- rfile abcdchk
- rfile tzreduce
- rfile housh
-
- tzero = function(a,b,c,d)
- {
- local(msg,estr,nn,nx,pp,mmtf,z,gain,bf,A,Zeps,mm,tf,mu,nu,Rank,numu,mnu,...
- af,nu1,i0,i1,i,dummy,s,zero,cols)
-
- // Check if (a,b,c,d) is correct
- msg=abcdchk(a,b,c,d);
- if (msg != "") {
- estr="TZERO: "+msg;
- error(estr);
- }
-
- // Special Case of an empty b and c matrices
- if ( (isempty(b)) && (isempty(c))) {
- z=[];
- gain
- return << z=z; gain=gain >>
- }
-
- Zeps=2*epsilon()*norm(a,"fro");
-
- nn=a.nr;
- nx=a.nc;
- pp=c.nr;
- mm=b.nc;
- if ( (pp*mm) == 1) {
- tf=1;
- else
- tf=0;
- }
-
- //* Construct the Compound Matrix [ B A ] of Dimension (N+P)x(M+N)
- //* [ D C ]
-
- bf=[b,a;d,c];
-
- //* Reduce this system to one with the same invariant zeros and with
- //* D full rank MU (The Normal Rank of the original system).
- //*
-
- A=tzreduce(bf,mm,nn,pp,Zeps,pp,0);
- bf=A.abcd;
- mu=A.mu;
- nu=A.nu;
- Rank=mu;
-
- if (nu == 0) {
- z=[];
- else
- //* Pretranspose the system
- numu=nu+mu;
- mnu=mm+nu;
- af=zeros(mnu,numu);
- af[mnu:1:-1;numu:-1:1]=bf[1:numu;1:mnu]';
-
- if (mu != mm) {
- pp=mm;
- nn=nu;
- mm=mu;
-
- //* Reduce the system to one with the same invariant zeros and with
- //* D square invertible.
-
- A=tzreduce(af,mm,nn,pp,Zeps,pp-mm,mm);
- af=A.abcd;
- mu=A.mu;
- nu=A.nu;
- mnu=mm+nu;
- }
-
- if (nu == 0) {
- z=[];
- else
- //* Perform a unitary transformation on the columns of [ sI-A B ] in
- //* [ sBf-Af X ] [ -C D ]
- //* order to reduce it to [ 0 Y ] with Y and Bf square invertible.
-
- bf[1:nu;1:mnu]=[zeros(nu,mm),eye(nu,nu)];
- if (Rank!= 0) {
- nu1=nu+1;
- i1=nu+mu;
- i0 = mm;
- for (i in 1:mm) {
- i0=i0-1;
- cols=i0+[1:nu1];
- dummy=af[i1;cols];
- A=housh(dummy,nu1,Zeps);
- dummy=A.u;
- s=A.s;
- zero=A.zero;
- af[1:i1;cols]=af[1:i1;cols]*(eye(nu1,nu1)-s*dummy*dummy');
- bf[1:nu;cols]=bf[1:nu;cols]*(eye(nu1,nu1)-s*dummy*dummy');
- i1=i1-1;
- }
- }
-
- //* Solve Generalized zeros of sBF - AF
- z=eig(af[1:nu;1:nu]/bf[1:nu;1:nu]).val;
- }
- }
-
- if (tf) {
- if (nu == nx) {
- gain=bf[nu+1;1];
- else
- gain=bf[nu+1;1]*prod(diag(bf[nu+2:nx+1;nu+2:nx+1]));
- }
- }
-
- return << z=z; gain=gain >>
- };
-