home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / octa21eb.zip / octave / SCRIPTS.ZIP / scripts / control / is_dgkf.m < prev    next >
Text File  |  1999-03-05  |  7KB  |  229 lines

  1. # Copyright (C) 1996,1998 A. Scottedward Hodel 
  2. #
  3. # This file is part of Octave. 
  4. #
  5. # Octave is free software; you can redistribute it and/or modify it 
  6. # under the terms of the GNU General Public License as published by the 
  7. # Free Software Foundation; either version 2, or (at your option) any 
  8. # later version. 
  9. # Octave is distributed in the hope that it will be useful, but WITHOUT 
  10. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
  11. # FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License 
  12. # for more details.
  13. # You should have received a copy of the GNU General Public License 
  14. # along with Octave; see the file COPYING.  If not, write to the Free 
  15. # Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 
  16.  
  17. function [retval,dgkf_struct] = is_dgkf(Asys,nu,ny,tol)
  18.   # function [retval,dgkf_struct] = is_dgkf(Asys,nu,ny{,tol})
  19.   # Determine whether a continuous time state space system meets
  20.   # assumptions of DGKF algorithm.  
  21.   # Partitions system into: [z] = [A  | Bw  Bu  ][w]
  22.   #                         [y]   [Cz | Dzw Dzu ][u]
  23.   #                               [Cy | Dyw Dyu ]
  24.   #If necessary, orthogonal transformations Qw, Qz and nonsingular
  25.   # transformations Ru, Ry are applied to respective vectors w, z, u, y 
  26.   # in order to satisfy DGKF assumptions.  Loop shifting is used if Dyu block
  27.   # is nonzero.
  28.   #
  29.   # inputs: 
  30.   #        Asys: structured system
  31.   #       nu: number of controlled inputs
  32.   #        ny: number of measured outputs
  33.   #        tol: threshhold for 0.  Default: 200*eps
  34.   # outputs: 
  35.   #    retval: true(1) if system passes check, false(0) otherwise
  36.   #    dgkf_struct: data structure of is_dgkf results.  Entries:
  37.   #      nw, nz: dimensions of w, z
  38.   #      A: system A matrix
  39.   #      Bw: (n x nw) Qw-transformed disturbance input matrix
  40.   #      Bu: (n x nu) Ru-transformed controlled input matrix;
  41.   #          Note: B = [Bw Bu] 
  42.   #      Cz: (nz x n) Qz-transformed error output matrix
  43.   #      Cy: (ny x n) Ry-transformed measured output matrix 
  44.   #          Note: C = [Cz; Cy] 
  45.   #      Dzu, Dyw: off-diagonal blocks of transformed D matrix that enter 
  46.   #          z, y from u, w respectively
  47.   #      Ru: controlled input transformation matrix 
  48.   #      Ry: observed output transformation matrix
  49.   #      Dyu_nz: nonzero if the Dyu block is nonzero.
  50.   #      Dyu: untransformed Dyu block
  51.   #      dflg: nonzero if the system is discrete-time
  52.   #   
  53.   #    is_dgkf exits with an error if the system is mixed discrete/continuous
  54.   #
  55.   # [1] Doyle, Glover, Khargonekar, Francis, "State Space Solutions
  56.   #     to Standard H2 and Hinf Control Problems," IEEE TAC August 1989
  57.   #
  58.   # [2] Maciejowksi, J.M.: "Multivariable feedback design,"
  59.   #     Addison-Wesley, 1989, ISBN 0-201-18243-2
  60.   #
  61.   # [3] Keith Glover and John C. Doyle: "State-space formulae for all
  62.   #     stabilizing controllers that satisfy and h-infinity-norm bound
  63.   #     and relations to risk sensitivity,"
  64.   #     Systems & Control Letters 11, Oct. 1988, pp 167-172.
  65.   # [4] P. A. Iglesias and K. Glover, "State-space approach to discrete-time
  66.   #     H-infinity control."  Int. J. Control, 1991, V. 54, #5, 1031-1073.
  67.   #
  68.   
  69.   #  Written by A. S. Hodel
  70.   #  Updated by John Ingram July 1996 to accept structured systems
  71.   #
  72.   # Revised by Kai P Mueller April 1998 to solve the general H_infinity
  73.   # problem using unitary transformations Q (on w and z)
  74.   # and non-singular transformations R (on u and y) such
  75.   # that the Dzu and Dyw matrices of the transformed plant
  76.   #
  77.   #    ~
  78.   #    P  (the variable Asys here)
  79.   #
  80.   # become
  81.   #
  82.   #    ~            -1         T
  83.   #    D  = Q   D   R   = [ 0 I ]  or [ I ],
  84.   #     12   12  12  12
  85.   #
  86.   #    ~            T
  87.   #    D  = R   D   Q   = [ 0 I ] or [ I ].
  88.   #     21   21  21  21
  89.   #
  90.   # This transformation together with the algorithm in [1] solves
  91.   # the general problem (see [2] for example). 
  92.  
  93.   if (nargin < 3) | (nargin > 4)
  94.     usage("[retval,dgkf_struct] = is_dgkf(Asys,nu,ny{,tol})");
  95.   elseif (! is_scalar(nu) | ! is_scalar(ny) )
  96.     error("is_dgkf: arguments 2 and 3 must be scalars")
  97.   elseif (! is_struct(Asys) )
  98.     error("Argument 1 must be a system data structure");
  99.   endif
  100.   if(nargin < 4)
  101.     tol = 200*eps;
  102.   elseif( !is_sample(tol) )
  103.     error("is_dgkf: tol must be a positive scalar")
  104.   endif
  105.  
  106.   retval = 1;        # assume passes test
  107.  
  108.   dflg = is_digital(Asys);
  109.   [Anc, Anz, nin, nout ] = sysdimensions(Asys);
  110.  
  111.   if( Anz == 0 & Anc == 0 )
  112.     error("is_dgkf: no system states");
  113.   elseif( nu >= nin )
  114.     error("is_dgkf: insufficient number of disturbance inputs");
  115.   elseif( ny >= nout )
  116.     error("is_dgkf: insufficient number of regulated outputs");
  117.   endif
  118.  
  119.   nw = nin - nu;           nw1 = nw + 1;
  120.   nz = nout - ny;          nz1 = nz + 1;
  121.  
  122.   [A,B,C,D] = sys2ss(Asys);
  123.   # scale input/output for numerical reasons
  124.   if(norm(C,'fro')*norm(B,'fro') == 0)
  125.     error("||C||*||B|| = 0; no dynamic connnection from inputs to outputs");
  126.   endif
  127.   xx = sqrt(norm(B, Inf) / norm(C, Inf));
  128.   B = B / xx;  C = C * xx;
  129.  
  130.   # partition matrices
  131.               Bw = B(:,1:nw);        Bu = B(:,nw1:nin);
  132.   Cz = C(1:nz,:);    Dzw = D(1:nz,1:nw);    Dzu = D(1:nz,nw1:nin);
  133.   Cy = C(nz1:nout,:);    Dyw = D(nz1:nout,1:nw);    Dyu = D(nz1:nout,nw1:nin);
  134.  
  135.   # Check for loopo shifting
  136.   Dyu_nz = (norm(Dyu,Inf) != 0);
  137.   if (Dyu_nz)
  138.     warning("is_dgkf: D22 nonzero; performing loop shifting");
  139.   endif
  140.  
  141.   # 12 - rank condition at w = 0
  142.   xx =[A, Bu; Cz, Dzu];
  143.   [nr, nc] = size(xx);
  144.   irank = rank(xx);
  145.   if (irank != nc)
  146.     retval = 0;
  147.     warning(sprintf("rank([A Bu; Cz Dzu]) = %d, need %d; n=%d, nz=%d, nu=%d", ...
  148.     irank,nc,(Anc+Anz),nz,nu));
  149.     warning(" *** 12-rank condition violated at w = 0.");
  150.   endif
  151.  
  152.   # 21 - rank condition at w = 0
  153.   xx =[A, Bw; Cy, Dyw];
  154.   [nr, nc] = size(xx);
  155.   irank = rank(xx);
  156.   if (irank != nr)
  157.     retval = 0;
  158.     warning(sprintf("rank([A Bw; Cy Dyw]) = %d, need %d; n=%d, ny=%d, nw=%d", ...
  159.     irank,nr,(Anc+Anz),ny,nw));
  160.     warning(" *** 21-rank condition violated at w = 0.");
  161.   endif
  162.  
  163.   # can Dzu be transformed to become [0 I]' or [I]?
  164.   # This ensures a normalized weight
  165.   [Qz, Ru] = qr(Dzu);
  166.   irank = rank(Ru);
  167.   if (irank != nu)
  168.     retval = 0;
  169.     warning(sprintf("*** rank(Dzu(%d x %d) = %d", nz, nu, irank));
  170.     warning(" *** Dzu does not have full column rank.");
  171.   endif
  172.   if (nu >= nz)
  173.     Qz = Qz(:,1:nu)';
  174.   else
  175.     Qz = [Qz(:,(nu+1):nz), Qz(:,1:nu)]';
  176.   endif
  177.   Ru = Ru(1:nu,:);
  178.  
  179.   # can Dyw be transformed to become [0 I] or [I]?
  180.   # This ensures a normalized weight
  181.   [Qw, Ry] = qr(Dyw');
  182.   irank = rank(Ry);
  183.   if (irank != ny)
  184.     retval = 0;
  185.     warning(sprintf("*** rank(Dyw(%d x %d) = %d", ny, nw, irank));
  186.     warning(" *** Dyw does not have full row rank.");
  187.   endif
  188.  
  189.   if (ny >= nw)
  190.     Qw = Qw(:,1:ny);
  191.   else
  192.     Qw = [Qw(:,(ny+1):nw), Qw(:,1:ny)];
  193.   endif
  194.   Ry = Ry(1:ny,:)';
  195.  
  196.   # transform P by Qz/Ru and Qw/Ry
  197.   Bw  = Bw*Qw;
  198.   Bu  = Bu/Ru;
  199.   B   = [Bw, Bu];
  200.   Cz  = Qz*Cz;
  201.   Cy  = Ry\Cy;
  202.   C   = [Cz; Cy];
  203.   Dzw = Qz*Dzw*Qw;
  204.   Dzu = Qz*Dzu/Ru;
  205.   Dyw = Ry\Dyw*Qw;
  206.  
  207.   # pack the return structure
  208.   dgkf_struct.nw    = nw;
  209.   dgkf_struct.nu    = nu;
  210.   dgkf_struct.nz    = nz;
  211.   dgkf_struct.ny    = ny;
  212.   dgkf_struct.A        = A;
  213.   dgkf_struct.Bw    = Bw;
  214.   dgkf_struct.Bu    = Bu;
  215.   dgkf_struct.Cz    = Cz;
  216.   dgkf_struct.Cy    = Cy;
  217.   dgkf_struct.Dzw    = Dzw;
  218.   dgkf_struct.Dzu    = Dzu;
  219.   dgkf_struct.Dyw    = Dyw;
  220.   dgkf_struct.Dyu    = Dyu;
  221.   dgkf_struct.Ru    = Ru;
  222.   dgkf_struct.Ry    = Ry;
  223.   dgkf_struct.Dyu_nz    = Dyu_nz;
  224.   dgkf_struct.dflg    = dflg;
  225.  
  226. endfunction
  227.