home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 4 / DATAFILE_PDCD4.iso / languages / rlab1_23a / CTB / tzreduce < prev    next >
Text File  |  1995-11-14  |  6KB  |  201 lines

  1. //-------------------------------------------------------------------------------
  2. //
  3. // tzreduce
  4. //
  5. // Syntax: A=tzreduce(abcd,m,n,p,zeps,ro,sigma)
  6. //
  7. // This routine extracts the reduced system (a,b,c,d) with d having full row
  8. // rank from the original system (a,b,c,d).
  9. //
  10. // Calling the routine as,
  11. //    [ABCD,MU,NU] = TZREDUCE(ABCD,M,N,P,Zeps,RO,SIGMA)
  12. //
  13. // Extracts from the (N+P)x(M+N) system [ B A ],  a (NU+MU)x(M+NU) 'reduced' 
  14. //        [ B' A' ]                     [ D C ]
  15. // system [ D' C' ] having the same transmission zeros but with D' Full Row 
  16. // Rank.  The system [ A' B' C' D' ] overwrites the old system.
  17. //
  18. // REFERENCE: Ported to RLaB from the FORTRAN Code contained in:
  19. // Emami-Naeini, A., and Van Dooren, A., "Computation of Zeros of Linear
  20. // Multivaraible Systems," Automatica, Vol. 18, No. 4, April 1982, pp. 415-430.
  21. //
  22. // The results are returned in a list:
  23. //
  24. // A.abcd = abcd;
  25. // A.mu = mu;
  26. // A.nu = nu;
  27. //
  28. // Copyright (C), by Jeffrey B. Layton, 1994
  29. // Version JBL 931024
  30. //-------------------------------------------------------------------------------
  31.  
  32. rfile housh
  33.  
  34. tzreduce = function(abcd,m,n,p,Zeps,ro,sigma)
  35. {
  36.    local(Sum2,mu,nu,ro1,mnu,numu,dummy,A,rows,icol,irow,s,i,...
  37.          zero,mu,nu,dum,ibar,Rows,Adum,tau,i1,mm1,n1,i2,mn1,cols,m1)
  38.  
  39.    Sum2=zeros(1,max(p,m));
  40.    mu=p;
  41.    nu=n;
  42.    while (mu != 0) {
  43.  
  44.       ro1=ro;
  45.       mnu=m+nu;
  46.       numu=nu+mu;
  47.  
  48.       if (m != 0 ) {
  49.           ro1=ro1+1;
  50.           irow=nu;
  51.  
  52. // *** Compress rows of D.  First exploit triangular shape
  53.          m1=sigma-1;
  54.          for (icol in 1:m1) {
  55.               rows=irow+[1:ro1];
  56.               dummy=abcd[rows,icol];
  57.               A=housh(dummy,1,Zeps);
  58.               dummy=A.u;
  59.               s=A.s;
  60.               zero=A.zero;
  61. // The following performs the same as the subroutine TR1 in the ref.
  62.               abcd[rows;icol:mnu]=(eye(ro1,ro1)-s*dummy*dummy')*abcd[rows;icol:mnu];
  63.               irow=irow+1;
  64.          }
  65.  
  66. // *** Continue with Householder with Pivoting ***
  67.  
  68.           if (sigma == 0) {
  69.               sigma=1;
  70.               ro1=ro1-1;
  71.           }
  72.  
  73.           if (sigma != m) {
  74. // Special case for ro1=1
  75.               if (ro1 == 1) {
  76.                   Sum2[sigma:m]=abcd[irow+1;sigma:m].*abcd[irow+1;sigma:m];
  77.               else
  78.         Sum2[sigma:m]=sum(abcd[irow+1:irow+ro1;sigma:m].*abcd[irow+1:irow+ro1;sigma:m]);
  79.               }
  80.           }
  81.  
  82.           for (icol in sigma:m) {
  83.  
  84. // *** Pivot if necessary ***
  85.  
  86.                if (icol != m) {
  87. // The following 4 lines perform the same as the subroutine PIVOT in the ref.
  88.                    Rows=1:numu;
  89.                    dum=max(Sum2[icol:m]);
  90.                    ibar=maxi(Sum2[icol:m]);
  91.                    ibar=ibar+icol-1;
  92.                    if (ibar != icol) {
  93.                        Sum2[ibar]=Sum2[icol];
  94.                        Sum2[icol]=dum;
  95.                        dum=abcd[Rows;icol];
  96.                        abcd[Rows;icol]=abcd[Rows;ibar];
  97.                        abcd[Rows;ibar]=dum;
  98.                    }
  99.                }
  100.  
  101. // *** Perform Householder Transformation ***
  102.  
  103.                dummy=abcd[irow+1:irow+ro1;icol];
  104.                Adum=housh(dummy,1,Zeps);
  105.                dummy=Adum.u;
  106.                s=Adum.s;
  107.                if (Adum.zero) {
  108.                    break;
  109.                }
  110.                if (ro1 == 1) {
  111.                    return << abcd=abcd; mu=mu; nu=nu >>
  112.                }
  113. // This next line replaces routine TR1 in the ref.
  114.       abcd[irow+1:irow+ro1;icol:mnu]=(eye(ro1,ro1)-s*dummy*dummy')*abcd[irow+1:irow+ro1;icol:mnu];
  115.                irow=irow+1;
  116.                ro1=ro1-1;
  117.                Sum2[icol:m]=Sum2[icol:m]-abcd[irow;icol:m] .* abcd[irow;icol:m];
  118.           }
  119.  
  120.       }
  121.       tau=ro1;
  122.       sigma=mu-tau;
  123.  
  124. // *** Compress the columns of C ***
  125.       if (nu <= 0) {
  126.           mu=sigma;
  127.           nu=0;
  128.           return << abcd=abcd; mu=mu; nu=nu >>
  129.       }
  130.  
  131.       i1=nu+sigma;
  132.       mm1=m+1;
  133.       n1=nu;
  134.       if (tau != 1) {
  135. // Special case of mm1=1
  136.           if (mm1 == mnu) {
  137.               Sum2[1:tau]=(abcd[i1+1:i1+tau;mm1].*abcd[i1+1:i1+tau;mm1])';
  138.           else
  139. // General case of mm1 != 1
  140.               Sum2[1:tau]=sum([abcd[i1+1:i1+tau;mm1:mnu].*abcd[i1+1:i1+tau;mm1:mnu]]');
  141.           }
  142.       }
  143.  
  144.       for (ro1 in 1:tau) {
  145.            ro=ro1-1;
  146.            i=tau-ro;
  147.            i2=i+i1;
  148.  
  149. // *** Pivot if necessary ***
  150.  
  151.            if (i != 1) {
  152. // The next 2 lines replace the routine PIVOT in the ref.
  153.               dum=max(Sum2[1:i]);
  154.               ibar=maxi(Sum2[1:i]);
  155.  
  156.               if (ibar != i) {
  157.                   Sum2[ibar]=Sum2[i];
  158.                   Sum2[i]=dum;
  159.                   dum = abcd[i2;mm1:mnu];
  160.                   abcd[i2;mm1:mnu] = abcd[ibar+i1;mm1:mnu];
  161.                   abcd[ibar+i1;mm1:mnu] = dum;
  162.               }
  163.            }
  164.  
  165. // *** Perform Householder Transformation ***
  166.   
  167.            cols=m+[1:n1];
  168.            dummy=abcd[i2;cols];
  169.            A=housh(dummy,n1,Zeps);
  170.            dummy=A.u;
  171.            s=A.s;
  172.            if (A.zero) {
  173.                break;
  174.            }
  175.            if (n1 != 1) {
  176. // The following line replaces routine TR2 in the ref.
  177.               abcd[1:i2;cols] = abcd[1:i2;cols]*(eye(n1,n1)-s*dummy*dummy');
  178.               mn1=m+n1;
  179.               abcd[1:n1;1:mn1]=(eye(n1,n1)-s*dummy*dummy')*abcd[1:n1;1:mn1];
  180.               Sum2[1:i]=Sum2[1:i]-abcd[i1+1:i1+i;mn1]' .* abcd[i1+1:i1+i;mn1]';
  181.               mnu=mnu-1;
  182.            }
  183.            n1=n1-1;
  184.  
  185.       }
  186.  
  187.       if (!A.zero) {
  188.           ro=tau;
  189.       }
  190.  
  191.       nu=nu-ro;
  192.       mu=sigma+ro;
  193.   
  194.       if (ro == 0) {
  195.           return << abcd=abcd; mu=mu; nu=nu >>
  196.       }
  197.    }
  198.  
  199.    return << abcd=abcd; mu=mu; nu=nu >>
  200. };
  201.