home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / r / rlab / CTB / glqr < prev    next >
Encoding:
Text File  |  1995-11-15  |  5.4 KB  |  193 lines

  1. //----------------------------------------------------------------------------
  2. //
  3. // glqr
  4. //
  5. // Syntax: G=glqr(A,DA,B,DB,Q,DQ,R,DR,CT,DCT)
  6. //
  7. // This routine computes the gradient of the LQR control design with respect
  8. // to a scalar parameter 'p' for Continuous Systems. It returns the gradient
  9. // of the optimal feedback gain matrix with respect to 'p'. It also returns
  10. // the gradient of the Riccatti Equation:
  11. //
  12. //                 -1
  13. //   A'P + PA - PBR  B'P + Q = 0
  14. //
  15. // Note: Two matrices are returned in a list.
  16. //
  17. //       G.dk = Gradient of Optimal Feedback Gain matrix
  18. //       G.dp = Gradient of Steady-State Solution to ARE.
  19. //
  20. // Ref: (1) Kailath, "Linear Systems," Prentice-Hall, 1980
  21. //      (2) Laub, A. J., "A Schur Method for Solving Algebraic Riccati
  22. //          Equations," IEEE Trans. AC-24, 1979, pp. 913-921.
  23. //      (3) Junkins, J., and Kim, Y., "Introduction to Dynamics and Control
  24. //          of Flexible Structures," AIAA Inc, Washington D.C., 1993.
  25. //
  26. // Copyright (C), by Jeffrey B. Layton, 1994
  27. // Version JBL 940918
  28. //----------------------------------------------------------------------------
  29.  
  30. rfile abcdchk
  31. rfile ric
  32. rfile gric
  33.  
  34. static (glqr_compute)    // Hide this function
  35.  
  36. glqr = function(a,da,b,db,q,dq,r,dr,ct,dct)
  37. {
  38.    local (nargs,msg,estr)
  39.  
  40. // Count number of inpute arguments
  41.    nargs=0;
  42.    if (exist(a)) {nargs=nargs+1;}
  43.    if (exist(da)) {nargs=nargs+1;}
  44.    if (exist(b)) {nargs=nargs+1;}
  45.    if (exist(db)) {nargs=nargs+1;}
  46.    if (exist(q)) {nargs=nargs+1;}
  47.    if (exist(dq)) {nargs=nargs+1;}
  48.    if (exist(r)) {nargs=nargs+1;}
  49.    if (exist(dr)) {nargs=nargs+1;}
  50.    if (exist(ct)) {nargs=nargs+1;}
  51.    if (exist(dct)) {nargs=nargs+1;}
  52.  
  53.    if ( (nargs != 8) || (nargs != 10) ) {
  54.        error("DLQR: Wrong number of input arguments.");
  55.    }
  56.  
  57. // Check Matrix Dimensions
  58. // -----------------------
  59.  
  60. // Check if Q and R are consistent.
  61.    if ( a.nr != q.nr || a.nc != q.nc ) {
  62.        error("GLQR: A and Q must be the same size");
  63.    }
  64.    
  65.    if ( r.nr != r.nc || b.nc != r.nr ) {
  66.        error("GLQR: B and R must be consistent");
  67.    }
  68.    
  69. // Check if A and B are empty
  70.    if ( (!length(a)) || (!length(b)) ) {
  71.        error("GLQR: A and B matrices cannot be empty.");
  72.    }
  73.  
  74. // A has to be square
  75.    if (a.nr != a.nc) {
  76.        error("GLQR: A has to be square.");
  77.    }
  78.  
  79. // Check gradient matrices
  80. // -----------------------
  81.  
  82. // Check if DQ and DR are consistent.
  83.    if ( da.nr != dq.nr || da.nc != dq.nc ) {
  84.        error("GLQR: DA and DQ must be the same size");
  85.    }
  86.    
  87.    if ( dr.nr != dr.nc || db.nc != dr.nr ) {
  88.        error("GLQR: DB and DR must be consistent");
  89.    }
  90.    
  91. // Check if DA and DB are empty
  92.    if ( (!length(da)) || (!length(db)) ) {
  93.        error("GLQR: DA and DB matrices cannot be empty.");
  94.    }
  95.  
  96. // DA has to be square
  97.    if (da.nr != da.nc) {
  98.        error("GLQR: DA has to be square.");
  99.    }
  100.  
  101. // See if A and B are compatible.
  102.    msg="";
  103.    msg=abcdchk(a,b);
  104.    if (msg != "") {
  105.        estr="GLQR: "+msg;
  106.        error(estr);
  107.    }
  108.  
  109. // Check if Q is positive semi-definite and symmetric
  110.    if (!issymm(q)) {
  111.        printf("%s","GLQR: Warning: Q is not symmetric.\n");
  112.    else
  113.        if (any(eig(q).val < -epsilon()*norm(q,"1")) ) {    
  114.            printf("%s","GLQR: Warning: Q is not positive semi-definite.\n");
  115.        }
  116.    }
  117.  
  118. // Check if R is positive definite and symmetric
  119.    if (!issymm(r)) {
  120.        printf("%s","GLQR: Warning: R is not symmetric.\n");
  121.    else
  122.        if (any(eig(r).val < -epsilon()*norm(r,"1")) ) {
  123.            printf("%s","GLQR: Warning: R is not positive semi-definite.\n");
  124.        }
  125.    }
  126.  
  127. //
  128. // Call glqr_compute with revised arguments. This prevents us from needlessly
  129. // making a copy if ct does not exist, and also prevents us from overwriting
  130. // a and q if ct exists.
  131. //
  132.  
  133. // Call static routine to compute results
  134.    if (exist(ct)) {
  135.        if ( ct.nr != a.nr || ct.nc != r.nc) {
  136.             error("GLQR: CT must be consistent with Q and R");
  137.        }
  138.        if ( dct.nr != da.nr || dct.nc != dr.nc) {
  139.             error("GLQR: DCT must be consistent with DQ and DR");
  140.        }
  141.        return glqr_compute(a,da,b,db,q,dq,r,dr,ct,dct);
  142. //     return glqr_compute (a-solve(r',b')'*ct', b, ...
  143. //                         q-solve(r',ct')'*ct', r, ct);
  144.    else
  145.        return glqr_compute(a,da,b,db,q,dq,r,dr,zeros(a.nr,b.nc),zeros(a.nr,b.nc));
  146. //     return glqr_compute (a, b, q, r, zeros (a.nr, b.nc));
  147.    }
  148. };
  149.  
  150. //----------------------------------------------------------------------------
  151. //
  152. // This is where the computation is performed. Note that glqr_compute is a
  153. // static variable and is never seen from the global workspace.
  154. //
  155.  
  156. glqr_compute = function(a,da,b,db,q,dq,r,dr,ct,dct)
  157. {
  158.    local (alocal, qlocal, dalocal, dqlocal, k, p, dp, dk)
  159.  
  160. // Modify the A and Q matrices
  161.    if (exist(ct)) {
  162.        alocal=a-solve(r',b')'*ct';
  163.        qlocal=q-solve(r',ct')'*ct';
  164.    else
  165.        alocal=a;
  166.        qlocal=q;
  167.    }
  168.  
  169. // Solve the Riccatti equation
  170.    p=ric(alocal,b,qlocal,r);
  171.  
  172. // Create matrices for input to gric
  173.    if (exist(ct)) {
  174.        dqlocal=dq-(dct/r)*ct' + (ct/r)*(dr/r)*ct' - (ct/r)*ct';
  175.        dalocal=da-(db/r)*ct' + (b/r)*(dr/r)*ct' - (b/r)*ct';
  176.    else
  177.        dalocal=da;
  178.        dqlocal=dq;
  179.    }
  180.  
  181. // Compute Gradient of Riccatti solution
  182.    dp = gric(a,dqlocallocal,b,db,q,dq,r,dr);
  183.  
  184. // Compute gradient of the gains
  185.    if (exist(ct)) {
  186.        dk=-(r\dr)*(r\(ct'+b'*p)) + r\(dct'+db'*p+b'*dp);
  187.    else
  188.        dk=-(r\dr)*(r\(b'*p)) + r\(db'*p) + r\(b'*dp);
  189.    }
  190.    
  191.    return << dk=dk; dp=dp >>;
  192. };
  193.