Mercurial > forge
changeset 8240:d61c0169b4fc octave-forge
control: add discrete-time support to ncfsyn (case D==0)
author | paramaniac |
---|---|
date | Sun, 31 Jul 2011 21:57:09 +0000 |
parents | 4aa6b72d861b |
children | c8d721d2a848 |
files | main/control/devel/ncfsyn/SB02OD.f main/control/devel/ncfsyn/SB02OU.f main/control/devel/ncfsyn/SB02OV.f main/control/devel/ncfsyn/SB02OW.f main/control/devel/ncfsyn/SB02OY.f main/control/devel/ncfsyn/SB10ID.dat main/control/devel/ncfsyn/SB10ID.res main/control/devel/ncfsyn/SB10KD.dat main/control/devel/ncfsyn/SB10KD.f main/control/devel/ncfsyn/SB10KD.res main/control/devel/ncfsyn/SB10ZD.dat main/control/devel/ncfsyn/SB10ZD.f main/control/devel/ncfsyn/SB10ZD.res main/control/devel/ncfsyn/makefile_ncfsyn.m main/control/devel/ncfsyn/ncfsyn.m main/control/devel/ncfsyn/slsb10kd.cc |
diffstat | 16 files changed, 3889 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB02OD.f Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,856 @@ + SUBROUTINE SB02OD( DICO, JOBB, FACT, UPLO, JOBL, SORT, N, M, P, A, + $ LDA, B, LDB, Q, LDQ, R, LDR, L, LDL, RCOND, X, + $ LDX, ALFAR, ALFAI, BETA, S, LDS, T, LDT, U, + $ LDU, TOL, IWORK, DWORK, LDWORK, BWORK, INFO ) +C +C SLICOT RELEASE 5.0. +C +C Copyright (c) 2002-2010 NICONET e.V. +C +C This program is free software: you can redistribute it and/or +C modify it under the terms of the GNU General Public License as +C published by the Free Software Foundation, either version 2 of +C the License, or (at your option) any later version. +C +C This program is distributed in the hope that it will be useful, +C but WITHOUT ANY WARRANTY; without even the implied warranty of +C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +C GNU General Public License for more details. +C +C You should have received a copy of the GNU General Public License +C along with this program. If not, see +C <http://www.gnu.org/licenses/>. +C +C PURPOSE +C +C To solve for X either the continuous-time algebraic Riccati +C equation +C -1 +C Q + A'X + XA - (L+XB)R (L+XB)' = 0 (1) +C +C or the discrete-time algebraic Riccati equation +C -1 +C X = A'XA - (L+A'XB)(R + B'XB) (L+A'XB)' + Q (2) +C +C where A, B, Q, R, and L are N-by-N, N-by-M, N-by-N, M-by-M and +C N-by-M matrices, respectively, such that Q = C'C, R = D'D and +C L = C'D; X is an N-by-N symmetric matrix. +C The routine also returns the computed values of the closed-loop +C spectrum of the system, i.e., the stable eigenvalues lambda(1), +C ..., lambda(N) of the corresponding Hamiltonian or symplectic +C pencil, in the continuous-time case or discrete-time case, +C respectively. +C -1 +C Optionally, matrix G = BR B' may be given instead of B and R. +C Other options include the case with Q and/or R given in a +C factored form, Q = C'C, R = D'D, and with L a zero matrix. +C +C The routine uses the method of deflating subspaces, based on +C reordering the eigenvalues in a generalized Schur matrix pair. +C A standard eigenproblem is solved in the continuous-time case +C if G is given. +C +C ARGUMENTS +C +C Mode Parameters +C +C DICO CHARACTER*1 +C Specifies the type of Riccati equation to be solved as +C follows: +C = 'C': Equation (1), continuous-time case; +C = 'D': Equation (2), discrete-time case. +C +C JOBB CHARACTER*1 +C Specifies whether or not the matrix G is given, instead +C of the matrices B and R, as follows: +C = 'B': B and R are given; +C = 'G': G is given. +C +C FACT CHARACTER*1 +C Specifies whether or not the matrices Q and/or R (if +C JOBB = 'B') are factored, as follows: +C = 'N': Not factored, Q and R are given; +C = 'C': C is given, and Q = C'C; +C = 'D': D is given, and R = D'D; +C = 'B': Both factors C and D are given, Q = C'C, R = D'D. +C +C UPLO CHARACTER*1 +C If JOBB = 'G', or FACT = 'N', specifies which triangle of +C the matrices G and Q (if FACT = 'N'), or Q and R (if +C JOBB = 'B'), is stored, as follows: +C = 'U': Upper triangle is stored; +C = 'L': Lower triangle is stored. +C +C JOBL CHARACTER*1 +C Specifies whether or not the matrix L is zero, as follows: +C = 'Z': L is zero; +C = 'N': L is nonzero. +C JOBL is not used if JOBB = 'G' and JOBL = 'Z' is assumed. +C SLICOT Library routine SB02MT should be called just before +C SB02OD, for obtaining the results when JOBB = 'G' and +C JOBL = 'N'. +C +C SORT CHARACTER*1 +C Specifies which eigenvalues should be obtained in the top +C of the generalized Schur form, as follows: +C = 'S': Stable eigenvalues come first; +C = 'U': Unstable eigenvalues come first. +C +C Input/Output Parameters +C +C N (input) INTEGER +C The actual state dimension, i.e. the order of the matrices +C A, Q, and X, and the number of rows of the matrices B +C and L. N >= 0. +C +C M (input) INTEGER +C The number of system inputs. If JOBB = 'B', M is the +C order of the matrix R, and the number of columns of the +C matrix B. M >= 0. +C M is not used if JOBB = 'G'. +C +C P (input) INTEGER +C The number of system outputs. If FACT = 'C' or 'D' or 'B', +C P is the number of rows of the matrices C and/or D. +C P >= 0. +C Otherwise, P is not used. +C +C A (input) DOUBLE PRECISION array, dimension (LDA,N) +C The leading N-by-N part of this array must contain the +C state matrix A of the system. +C +C LDA INTEGER +C The leading dimension of array A. LDA >= MAX(1,N). +C +C B (input) DOUBLE PRECISION array, dimension (LDB,*) +C If JOBB = 'B', the leading N-by-M part of this array must +C contain the input matrix B of the system. +C If JOBB = 'G', the leading N-by-N upper triangular part +C (if UPLO = 'U') or lower triangular part (if UPLO = 'L') +C of this array must contain the upper triangular part or +C lower triangular part, respectively, of the matrix +C -1 +C G = BR B'. The stricly lower triangular part (if +C UPLO = 'U') or stricly upper triangular part (if +C UPLO = 'L') is not referenced. +C +C LDB INTEGER +C The leading dimension of array B. LDB >= MAX(1,N). +C +C Q (input) DOUBLE PRECISION array, dimension (LDQ,N) +C If FACT = 'N' or 'D', the leading N-by-N upper triangular +C part (if UPLO = 'U') or lower triangular part (if UPLO = +C 'L') of this array must contain the upper triangular part +C or lower triangular part, respectively, of the symmetric +C state weighting matrix Q. The stricly lower triangular +C part (if UPLO = 'U') or stricly upper triangular part (if +C UPLO = 'L') is not referenced. +C If JOBB = 'B', the triangular part of this array defined +C by UPLO is modified internally, but is restored on exit. +C If FACT = 'C' or 'B', the leading P-by-N part of this +C array must contain the output matrix C of the system. +C If JOBB = 'B', this part is modified internally, but is +C restored on exit. +C +C LDQ INTEGER +C The leading dimension of array Q. +C LDQ >= MAX(1,N) if FACT = 'N' or 'D', +C LDQ >= MAX(1,P) if FACT = 'C' or 'B'. +C +C R (input) DOUBLE PRECISION array, dimension (LDR,M) +C If FACT = 'N' or 'C', the leading M-by-M upper triangular +C part (if UPLO = 'U') or lower triangular part (if UPLO = +C 'L') of this array must contain the upper triangular part +C or lower triangular part, respectively, of the symmetric +C input weighting matrix R. The stricly lower triangular +C part (if UPLO = 'U') or stricly upper triangular part (if +C UPLO = 'L') is not referenced. +C The triangular part of this array defined by UPLO is +C modified internally, but is restored on exit. +C If FACT = 'D' or 'B', the leading P-by-M part of this +C array must contain the direct transmission matrix D of the +C system. This part is modified internally, but is restored +C on exit. +C If JOBB = 'G', this array is not referenced. +C +C LDR INTEGER +C The leading dimension of array R. +C LDR >= MAX(1,M) if JOBB = 'B' and FACT = 'N' or 'C'; +C LDR >= MAX(1,P) if JOBB = 'B' and FACT = 'D' or 'B'; +C LDR >= 1 if JOBB = 'G'. +C +C L (input) DOUBLE PRECISION array, dimension (LDL,M) +C If JOBL = 'N' (and JOBB = 'B'), the leading N-by-M part of +C this array must contain the cross weighting matrix L. +C This part is modified internally, but is restored on exit. +C If JOBL = 'Z' or JOBB = 'G', this array is not referenced. +C +C LDL INTEGER +C The leading dimension of array L. +C LDL >= MAX(1,N) if JOBL = 'N' and JOBB = 'B'; +C LDL >= 1 if JOBL = 'Z' or JOBB = 'G'. +C +C RCOND (output) DOUBLE PRECISION +C An estimate of the reciprocal of the condition number (in +C the 1-norm) of the N-th order system of algebraic +C equations from which the solution matrix X is obtained. +C +C X (output) DOUBLE PRECISION array, dimension (LDX,N) +C The leading N-by-N part of this array contains the +C solution matrix X of the problem. +C +C LDX INTEGER +C The leading dimension of array X. LDX >= MAX(1,N). +C +C ALFAR (output) DOUBLE PRECISION array, dimension (2*N) +C ALFAI (output) DOUBLE PRECISION array, dimension (2*N) +C BETA (output) DOUBLE PRECISION array, dimension (2*N) +C The generalized eigenvalues of the 2N-by-2N matrix pair, +C ordered as specified by SORT (if INFO = 0). For instance, +C if SORT = 'S', the leading N elements of these arrays +C contain the closed-loop spectrum of the system matrix +C A - BF, where F is the optimal feedback matrix computed +C based on the solution matrix X. Specifically, +C lambda(k) = [ALFAR(k)+j*ALFAI(k)]/BETA(k) for +C k = 1,2,...,N. +C If DICO = 'C' and JOBB = 'G', the elements of BETA are +C set to 1. +C +C S (output) DOUBLE PRECISION array, dimension (LDS,*) +C The leading 2N-by-2N part of this array contains the +C ordered real Schur form S of the first matrix in the +C reduced matrix pencil associated to the optimal problem, +C or of the corresponding Hamiltonian matrix, if DICO = 'C' +C and JOBB = 'G'. That is, +C +C (S S ) +C ( 11 12) +C S = ( ), +C (0 S ) +C ( 22) +C +C where S , S and S are N-by-N matrices. +C 11 12 22 +C Array S must have 2*N+M columns if JOBB = 'B', and 2*N +C columns, otherwise. +C +C LDS INTEGER +C The leading dimension of array S. +C LDS >= MAX(1,2*N+M) if JOBB = 'B', +C LDS >= MAX(1,2*N) if JOBB = 'G'. +C +C T (output) DOUBLE PRECISION array, dimension (LDT,2*N) +C If DICO = 'D' or JOBB = 'B', the leading 2N-by-2N part of +C this array contains the ordered upper triangular form T of +C the second matrix in the reduced matrix pencil associated +C to the optimal problem. That is, +C +C (T T ) +C ( 11 12) +C T = ( ), +C (0 T ) +C ( 22) +C +C where T , T and T are N-by-N matrices. +C 11 12 22 +C If DICO = 'C' and JOBB = 'G' this array is not referenced. +C +C LDT INTEGER +C The leading dimension of array T. +C LDT >= MAX(1,2*N+M) if JOBB = 'B', +C LDT >= MAX(1,2*N) if JOBB = 'G' and DICO = 'D', +C LDT >= 1 if JOBB = 'G' and DICO = 'C'. +C +C U (output) DOUBLE PRECISION array, dimension (LDU,2*N) +C The leading 2N-by-2N part of this array contains the right +C transformation matrix U which reduces the 2N-by-2N matrix +C pencil to the ordered generalized real Schur form (S,T), +C or the Hamiltonian matrix to the ordered real Schur +C form S, if DICO = 'C' and JOBB = 'G'. That is, +C +C (U U ) +C ( 11 12) +C U = ( ), +C (U U ) +C ( 21 22) +C +C where U , U , U and U are N-by-N matrices. +C 11 12 21 22 +C +C LDU INTEGER +C The leading dimension of array U. LDU >= MAX(1,2*N). +C +C Tolerances +C +C TOL DOUBLE PRECISION +C The tolerance to be used to test for near singularity of +C the original matrix pencil, specifically of the triangular +C factor obtained during the reduction process. If the user +C sets TOL > 0, then the given value of TOL is used as a +C lower bound for the reciprocal condition number of that +C matrix; a matrix whose estimated condition number is less +C than 1/TOL is considered to be nonsingular. If the user +C sets TOL <= 0, then a default tolerance, defined by +C TOLDEF = EPS, is used instead, where EPS is the machine +C precision (see LAPACK Library routine DLAMCH). +C This parameter is not referenced if JOBB = 'G'. +C +C Workspace +C +C IWORK INTEGER array, dimension (LIWORK) +C LIWORK >= MAX(1,M,2*N) if JOBB = 'B', +C LIWORK >= MAX(1,2*N) if JOBB = 'G'. +C +C DWORK DOUBLE PRECISION array, dimension (LDWORK) +C On exit, if INFO = 0, DWORK(1) returns the optimal value +C of LDWORK. If JOBB = 'B' and N > 0, DWORK(2) returns the +C reciprocal of the condition number of the M-by-M lower +C triangular matrix obtained after compressing the matrix +C pencil of order 2N+M to obtain a pencil of order 2N. +C If INFO = 0 or INFO = 6, DWORK(3) returns the scaling +C factor used internally, which should multiply the +C submatrix Y2 to recover X from the first N columns of U +C (see METHOD). +C +C LDWORK INTEGER +C The length of the array DWORK. +C LDWORK >= MAX(3,6*N), if JOBB = 'G', +C DICO = 'C'; +C LDWORK >= MAX(7*(2*N+1)+16,16*N), if JOBB = 'G', +C DICO = 'D'; +C LDWORK >= MAX(7*(2*N+1)+16,16*N,2*N+M,3*M), if JOBB = 'B'. +C For optimum performance LDWORK should be larger. +C +C BWORK LOGICAL array, dimension (2*N) +C +C Error Indicator +C +C INFO INTEGER +C = 0: successful exit; +C < 0: if INFO = -i, the i-th argument had an illegal +C value; +C = 1: if the computed extended matrix pencil is singular, +C possibly due to rounding errors; +C = 2: if the QZ (or QR) algorithm failed; +C = 3: if reordering of the (generalized) eigenvalues +C failed; +C = 4: if after reordering, roundoff changed values of +C some complex eigenvalues so that leading eigenvalues +C in the (generalized) Schur form no longer satisfy +C the stability condition; this could also be caused +C due to scaling; +C = 5: if the computed dimension of the solution does not +C equal N; +C = 6: if a singular matrix was encountered during the +C computation of the solution matrix X. +C +C METHOD +C +C The routine uses a variant of the method of deflating subspaces +C proposed by van Dooren [1]. See also [2], [3]. +C It is assumed that (A,B) is stabilizable and (C,A) is detectable. +C Under these assumptions the algebraic Riccati equation is known to +C have a unique non-negative definite solution. +C The first step in the method of deflating subspaces is to form the +C extended Hamiltonian matrices, dimension 2N + M given by +C +C discrete-time continuous-time +C +C |A 0 B| |I 0 0| |A 0 B| |I 0 0| +C |Q -I L| - z |0 -A' 0|, |Q A' L| - s |0 -I 0|. +C |L' 0 R| |0 -B' 0| |L' B' R| |0 0 0| +C +C Next, these pencils are compressed to a form (see [1]) +C +C lambda x A - B . +C f f +C +C This generalized eigenvalue problem is then solved using the QZ +C algorithm and the stable deflating subspace Ys is determined. +C If [Y1'|Y2']' is a basis for Ys, then the required solution is +C -1 +C X = Y2 x Y1 . +C A standard eigenvalue problem is solved using the QR algorithm in +C the continuous-time case when G is given (DICO = 'C', JOBB = 'G'). +C +C REFERENCES +C +C [1] Van Dooren, P. +C A Generalized Eigenvalue Approach for Solving Riccati +C Equations. +C SIAM J. Sci. Stat. Comp., 2, pp. 121-135, 1981. +C +C [2] Mehrmann, V. +C The Autonomous Linear Quadratic Control Problem. Theory and +C Numerical Solution. +C Lect. Notes in Control and Information Sciences, vol. 163, +C Springer-Verlag, Berlin, 1991. +C +C [3] Sima, V. +C Algorithms for Linear-Quadratic Optimization. +C Pure and Applied Mathematics: A Series of Monographs and +C Textbooks, vol. 200, Marcel Dekker, Inc., New York, 1996. +C +C NUMERICAL ASPECTS +C +C This routine is particularly suited for systems where the matrix R +C is ill-conditioned. Internal scaling is used. +C +C FURTHER COMMENTS +C +C To obtain a stabilizing solution of the algebraic Riccati +C equations set SORT = 'S'. +C +C The routine can also compute the anti-stabilizing solutions of +C the algebraic Riccati equations, by specifying SORT = 'U'. +C +C CONTRIBUTOR +C +C Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Sep. 1997. +C Supersedes Release 2.0 routine SB02CD by T.G.J. Beelen, Philips, +C Eindhoven, Holland. +C +C REVISIONS +C +C V. Sima, Katholieke Univ. Leuven, Belgium, May 1999, June 2002, +C December 2002, January 2005. +C +C KEYWORDS +C +C Algebraic Riccati equation, closed loop system, continuous-time +C system, discrete-time system, optimal regulator, Schur form. +C +C ****************************************************************** +C +C .. Parameters .. + DOUBLE PRECISION ZERO, HALF, ONE, THREE + PARAMETER ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0, + $ THREE = 3.0D0 ) +C .. Scalar Arguments .. + CHARACTER DICO, FACT, JOBB, JOBL, SORT, UPLO + INTEGER INFO, LDA, LDB, LDL, LDQ, LDR, LDS, LDT, LDU, + $ LDWORK, LDX, M, N, P + DOUBLE PRECISION RCOND, TOL +C .. Array Arguments .. + LOGICAL BWORK(*) + INTEGER IWORK(*) + DOUBLE PRECISION A(LDA,*), ALFAI(*), ALFAR(*), B(LDB,*), BETA(*), + $ DWORK(*), L(LDL,*), Q(LDQ,*), R(LDR,*), + $ S(LDS,*), T(LDT,*), U(LDU,*), X(LDX,*) +C .. Local Scalars .. + CHARACTER QTYPE, RTYPE + LOGICAL DISCR, LFACB, LFACN, LFACQ, LFACR, LJOBB, LJOBL, + $ LJOBLN, LSCAL, LSCL, LSORT, LUPLO + INTEGER I, INFO1, J, LDW, MP, NDIM, NN, NNM, NP, NP1, + $ WRKOPT + DOUBLE PRECISION QSCAL, RCONDL, RNORM, RSCAL, SCALE, UNORM +C .. Local Arrays .. + DOUBLE PRECISION DUM(1) +C .. External Functions .. + LOGICAL LSAME, SB02MR, SB02MV, SB02OU, SB02OV, SB02OW + DOUBLE PRECISION DLAMCH, DLANGE, DLANSY + EXTERNAL DLAMCH, DLANGE, DLANSY, LSAME, SB02MR, SB02MV, + $ SB02OU, SB02OV, SB02OW +C .. External Subroutines .. + EXTERNAL DAXPY, DCOPY, DGECON, DGEES, DGETRF, DGETRS, + $ DGGES, DLACPY, DLASCL, DLASET, DSCAL, DSWAP, + $ SB02OY, XERBLA +C .. Intrinsic Functions .. + INTRINSIC INT, MAX, MIN, SQRT +C .. Executable Statements .. +C + INFO = 0 + DISCR = LSAME( DICO, 'D' ) + LJOBB = LSAME( JOBB, 'B' ) + LFACN = LSAME( FACT, 'N' ) + LFACQ = LSAME( FACT, 'C' ) + LFACR = LSAME( FACT, 'D' ) + LFACB = LSAME( FACT, 'B' ) + LUPLO = LSAME( UPLO, 'U' ) + LSORT = LSAME( SORT, 'S' ) +C + NN = 2*N + IF ( LJOBB ) THEN + LJOBL = LSAME( JOBL, 'Z' ) + LJOBLN = LSAME( JOBL, 'N' ) + NNM = NN + M + LDW = MAX( NNM, 3*M ) + ELSE + NNM = NN + LDW = 1 + END IF + NP1 = N + 1 +C +C Test the input scalar arguments. +C + IF( .NOT.DISCR .AND. .NOT.LSAME( DICO, 'C' ) ) THEN + INFO = -1 + ELSE IF( .NOT.LJOBB .AND. .NOT.LSAME( JOBB, 'G' ) ) THEN + INFO = -2 + ELSE IF( .NOT.LFACQ .AND. .NOT.LFACR .AND. .NOT.LFACB + $ .AND. .NOT.LFACN ) THEN + INFO = -3 + ELSE IF( .NOT.LJOBB .OR. LFACN ) THEN + IF( .NOT.LUPLO .AND. .NOT.LSAME( UPLO, 'L' ) ) + $ INFO = -4 + END IF + IF( INFO.EQ.0 .AND. LJOBB ) THEN + IF( .NOT.LJOBL .AND. .NOT.LJOBLN ) + $ INFO = -5 + END IF + IF( INFO.EQ.0 ) THEN + IF( .NOT.LSORT .AND. .NOT.LSAME( SORT, 'U' ) ) THEN + INFO = -6 + ELSE IF( N.LT.0 ) THEN + INFO = -7 + ELSE IF( LJOBB ) THEN + IF( M.LT.0 ) + $ INFO = -8 + END IF + END IF + IF( INFO.EQ.0 .AND. .NOT.LFACN ) THEN + IF( P.LT.0 ) + $ INFO = -9 + END IF + IF( INFO.EQ.0 ) THEN + IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -11 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -13 + ELSE IF( ( ( LFACN.OR.LFACR ) .AND. LDQ.LT.MAX( 1, N ) ) .OR. + $ ( ( LFACQ.OR.LFACB ) .AND. LDQ.LT.MAX( 1, P ) ) ) THEN + INFO = -15 + ELSE IF( LDR.LT.1 ) THEN + INFO = -17 + ELSE IF( LDL.LT.1 ) THEN + INFO = -19 + ELSE IF( LJOBB ) THEN + IF ( ( LFACN.OR.LFACQ ) .AND. LDR.LT.M .OR. + $ ( LFACR.OR.LFACB ) .AND. LDR.LT.P ) THEN + INFO = -17 + ELSE IF( LJOBLN .AND. LDL.LT.N ) THEN + INFO = -19 + END IF + END IF + END IF + IF( INFO.EQ.0 ) THEN + IF( LDX.LT.MAX( 1, N ) ) THEN + INFO = -22 + ELSE IF( LDS.LT.MAX( 1, NNM ) ) THEN + INFO = -27 + ELSE IF( LDT.LT.1 ) THEN + INFO = -29 + ELSE IF( LDU.LT.MAX( 1, NN ) ) THEN + INFO = -31 + ELSE IF( LDWORK.LT.MAX( 3, 6*N ) ) THEN + INFO = -35 + ELSE IF( DISCR .OR. LJOBB ) THEN + IF( LDT.LT.NNM ) THEN + INFO = -29 + ELSE IF( LDWORK.LT.MAX( 14*N + 23, 16*N, LDW ) ) THEN + INFO = -35 + END IF + END IF + END IF +C + IF ( INFO.NE.0 ) THEN +C +C Error return. +C + CALL XERBLA( 'SB02OD', -INFO ) + RETURN + END IF +C +C Quick return if possible. +C + IF ( N.EQ.0 ) THEN + RCOND = ONE + DWORK(1) = THREE + DWORK(3) = ONE + RETURN + END IF +C +C Always scale the matrix pencil. +C + LSCAL = .TRUE. +C +C Start computations. +C +C (Note: Comments in the code beginning "Workspace:" describe the +C minimal amount of real workspace needed at that point in the +C code, as well as the preferred amount for good performance. +C NB refers to the optimal block size for the immediately +C following subroutine, as returned by ILAENV.) +C + IF ( LSCAL .AND. LJOBB ) THEN +C +C Scale the matrices Q, R, and L so that +C norm(Q) + norm(R) + norm(L) = 1, +C using the 1-norm. If Q and/or R are factored, the norms of +C the factors are used. +C Workspace: need max(N,M), if FACT = 'N'; +C N, if FACT = 'D'; +C M, if FACT = 'C'. +C + IF ( LFACN .OR. LFACR ) THEN + SCALE = DLANSY( '1-norm', UPLO, N, Q, LDQ, DWORK ) + QTYPE = UPLO + NP = N + ELSE + SCALE = DLANGE( '1-norm', P, N, Q, LDQ, DWORK ) + QTYPE = 'G' + NP = P + END IF +C + IF ( LFACN .OR. LFACQ ) THEN + RNORM = DLANSY( '1-norm', UPLO, M, R, LDR, DWORK ) + RTYPE = UPLO + MP = M + ELSE + RNORM = DLANGE( '1-norm', P, M, R, LDR, DWORK ) + RTYPE = 'G' + MP = P + END IF + SCALE = SCALE + RNORM +C + IF ( LJOBLN ) + $ SCALE = SCALE + DLANGE( '1-norm', N, M, L, LDL, DWORK ) + IF ( SCALE.EQ.ZERO ) + $ SCALE = ONE +C + IF ( LFACN .OR. LFACR ) THEN + QSCAL = SCALE + ELSE + QSCAL = SQRT( SCALE ) + END IF +C + IF ( LFACN .OR. LFACQ ) THEN + RSCAL = SCALE + ELSE + RSCAL = SQRT( SCALE ) + END IF +C + CALL DLASCL( QTYPE, 0, 0, QSCAL, ONE, NP, N, Q, LDQ, INFO1 ) + CALL DLASCL( RTYPE, 0, 0, RSCAL, ONE, MP, M, R, LDR, INFO1 ) + IF ( LJOBLN ) + $ CALL DLASCL( 'G', 0, 0, SCALE, ONE, N, M, L, LDL, INFO1 ) + END IF +C +C Construct the extended matrix pair. +C +C Workspace: need 1, if JOBB = 'G', +C max(1,2*N+M,3*M), if JOBB = 'B'; +C prefer larger. +C + CALL SB02OY( 'Optimal control', DICO, JOBB, FACT, UPLO, JOBL, + $ 'Identity E', N, M, P, A, LDA, B, LDB, Q, LDQ, R, + $ LDR, L, LDL, U, 1, S, LDS, T, LDT, TOL, IWORK, DWORK, + $ LDWORK, INFO ) +C + IF ( LSCAL .AND. LJOBB ) THEN +C +C Undo scaling of the data arrays. +C + CALL DLASCL( QTYPE, 0, 0, ONE, QSCAL, NP, N, Q, LDQ, INFO1 ) + CALL DLASCL( RTYPE, 0, 0, ONE, RSCAL, MP, M, R, LDR, INFO1 ) + IF ( LJOBLN ) + $ CALL DLASCL( 'G', 0, 0, ONE, SCALE, N, M, L, LDL, INFO1 ) + END IF +C + IF ( INFO.NE.0 ) + $ RETURN + WRKOPT = DWORK(1) + IF ( LJOBB ) RCONDL = DWORK(2) +C + IF ( LSCAL .AND. .NOT.LJOBB ) THEN +C +C This part of the code is used when G is given (JOBB = 'G'). +C A standard eigenproblem is solved in the continuous-time case. +C Scale the Hamiltonian matrix S, if DICO = 'C', or the +C symplectic pencil (S,T), if DICO = 'D', using the square roots +C of the norms of the matrices Q and G. +C Workspace: need N. +C + IF ( LFACN .OR. LFACR ) THEN + SCALE = SQRT( DLANSY( '1-norm', UPLO, N, Q, LDQ, DWORK ) ) + ELSE + SCALE = DLANGE( '1-norm', P, N, Q, LDQ, DWORK ) + END IF + RNORM = SQRT( DLANSY( '1-norm', UPLO, N, B, LDB, DWORK ) ) +C + LSCL = MIN( SCALE, RNORM ).GT.ZERO .AND. SCALE.NE.RNORM +C + IF( LSCL ) THEN + IF( DISCR ) THEN + CALL DLASCL( 'G', 0, 0, SCALE, RNORM, N, N, S(NP1,1), + $ LDS, INFO1 ) + CALL DLASCL( 'G', 0, 0, RNORM, SCALE, N, N, T(1,NP1), + $ LDT, INFO1 ) + ELSE + CALL DLASCL( 'G', 0, 0, SCALE, -RNORM, N, N, S(NP1,1), + $ LDS, INFO1 ) + CALL DLASCL( 'G', 0, 0, RNORM, SCALE, N, N, S(1,NP1), + $ LDS, INFO1 ) + CALL DLASCL( 'G', 0, 0, ONE, -ONE, N, N, S(NP1,NP1), + $ LDS, INFO1 ) + END IF + ELSE + IF( .NOT.DISCR ) THEN + CALL DLASCL( 'G', 0, 0, ONE, -ONE, N, NN, S(NP1,1), LDS, + $ INFO1 ) + END IF + END IF + ELSE + LSCL = .FALSE. + END IF +C +C Workspace: need max(7*(2*N+1)+16,16*N), +C if JOBB = 'B' or DICO = 'D'; +C 6*N, if JOBB = 'G' and DICO = 'C'; +C prefer larger. +C + IF ( DISCR ) THEN + IF ( LSORT ) THEN +C +C The natural tendency of the QZ algorithm to get the largest +C eigenvalues in the leading part of the matrix pair is +C exploited, by computing the unstable eigenvalues of the +C permuted matrix pair. +C + CALL DGGES( 'No vectors', 'Vectors', 'Sort', SB02OV, NN, T, + $ LDT, S, LDS, NDIM, ALFAR, ALFAI, BETA, U, LDU, + $ U, LDU, DWORK, LDWORK, BWORK, INFO1 ) + CALL DSWAP( N, ALFAR(NP1), 1, ALFAR, 1 ) + CALL DSWAP( N, ALFAI(NP1), 1, ALFAI, 1 ) + CALL DSWAP( N, BETA (NP1), 1, BETA, 1 ) + ELSE + CALL DGGES( 'No vectors', 'Vectors', 'Sort', SB02OV, NN, S, + $ LDS, T, LDT, NDIM, ALFAR, ALFAI, BETA, U, LDU, + $ U, LDU, DWORK, LDWORK, BWORK, INFO1 ) + END IF + ELSE + IF ( LJOBB ) THEN + IF ( LSORT ) THEN + CALL DGGES( 'No vectors', 'Vectors', 'Sort', SB02OW, NN, + $ S, LDS, T, LDT, NDIM, ALFAR, ALFAI, BETA, U, + $ LDU, U, LDU, DWORK, LDWORK, BWORK, INFO1 ) + ELSE + CALL DGGES( 'No vectors', 'Vectors', 'Sort', SB02OU, NN, + $ S, LDS, T, LDT, NDIM, ALFAR, ALFAI, BETA, U, + $ LDU, U, LDU, DWORK, LDWORK, BWORK, INFO1 ) + END IF + ELSE + IF ( LSORT ) THEN + CALL DGEES( 'Vectors', 'Sort', SB02MV, NN, S, LDS, NDIM, + $ ALFAR, ALFAI, U, LDU, DWORK, LDWORK, BWORK, + $ INFO1 ) + ELSE + CALL DGEES( 'Vectors', 'Sort', SB02MR, NN, S, LDS, NDIM, + $ ALFAR, ALFAI, U, LDU, DWORK, LDWORK, BWORK, + $ INFO1 ) + END IF + DUM(1) = ONE + CALL DCOPY( NN, DUM, 0, BETA, 1 ) + END IF + END IF + IF ( INFO1.GT.0 .AND. INFO1.LE.NN+1 ) THEN + INFO = 2 + ELSE IF ( INFO1.EQ.NN+2 ) THEN + INFO = 4 + ELSE IF ( INFO1.EQ.NN+3 ) THEN + INFO = 3 + ELSE IF ( NDIM.NE.N ) THEN + INFO = 5 + END IF + IF ( INFO.NE.0 ) + $ RETURN + WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) ) +C +C Select submatrices U1 and U2 out of the array U which define the +C solution X = U2 x inv(U1). +C Since X = X' we may obtain X as the solution of the system of +C linear equations U1' x X = U2', where +C U1 = U(1:n, 1:n), +C U2 = U(n+1:2n, 1:n). +C Use the (2,1) block of S as a workspace for factoring U1. +C + DO 20 J = 1, N + CALL DCOPY( N, U(NP1,J), 1, X(J,1), LDX ) + 20 CONTINUE +C + CALL DLACPY( 'Full', N, N, U, LDU, S(NP1,1), LDS ) +C +C Check if U1 is singular. +C + UNORM = DLANGE( '1-norm', N, N, S(NP1,1), LDS, DWORK ) +C +C Solve the system U1' x X = U2'. +C + CALL DGETRF( N, N, S(NP1,1), LDS, IWORK, INFO1 ) + IF ( INFO1.NE.0 ) THEN + INFO = 6 + DWORK(3) = ONE + IF ( LSCAL ) THEN + IF ( LJOBB ) THEN + DWORK(3) = SCALE + ELSE IF ( LSCL ) THEN + DWORK(3) = SCALE / RNORM + END IF + END IF + RETURN + ELSE +C +C Estimate the reciprocal condition of U1. +C Workspace: need 3*N. +C + CALL DGECON( '1-norm', N, S(NP1,1), LDS, UNORM, RCOND, DWORK, + $ IWORK(NP1), INFO ) +C + IF ( RCOND.LT.DLAMCH( 'Epsilon' ) ) THEN +C +C Nearly singular matrix. Set INFO for error return. +C + INFO = 6 + RETURN + END IF + WRKOPT = MAX( WRKOPT, 3*N ) + CALL DGETRS( 'Transpose', N, N, S(NP1,1), LDS, IWORK, X, LDX, + $ INFO1 ) +C +C Set S(2,1) to zero. +C + CALL DLASET( 'Full', N, N, ZERO, ZERO, S(NP1,1), LDS ) +C + IF ( LSCAL ) THEN +C +C Prepare to undo scaling for the solution X. +C + IF ( .NOT.LJOBB ) THEN + IF ( LSCL ) THEN + SCALE = SCALE / RNORM + ELSE + SCALE = ONE + END IF + END IF + DWORK(3) = SCALE + SCALE = HALF*SCALE + ELSE + DWORK(3) = ONE + SCALE = HALF + END IF +C +C Make sure the solution matrix X is symmetric. +C + DO 40 I = 1, N + CALL DAXPY( N-I+1, ONE, X(I,I), LDX, X(I,I), 1 ) + CALL DSCAL( N-I+1, SCALE, X(I,I), 1 ) + CALL DCOPY( N-I+1, X(I,I), 1, X(I,I), LDX ) + 40 CONTINUE + END IF +C + DWORK(1) = WRKOPT + IF ( LJOBB ) DWORK(2) = RCONDL +C + RETURN +C *** Last line of SB02OD *** + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB02OU.f Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,83 @@ + LOGICAL FUNCTION SB02OU( ALPHAR, ALPHAI, BETA ) +C +C SLICOT RELEASE 5.0. +C +C Copyright (c) 2002-2010 NICONET e.V. +C +C This program is free software: you can redistribute it and/or +C modify it under the terms of the GNU General Public License as +C published by the Free Software Foundation, either version 2 of +C the License, or (at your option) any later version. +C +C This program is distributed in the hope that it will be useful, +C but WITHOUT ANY WARRANTY; without even the implied warranty of +C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +C GNU General Public License for more details. +C +C You should have received a copy of the GNU General Public License +C along with this program. If not, see +C <http://www.gnu.org/licenses/>. +C +C PURPOSE +C +C To select the unstable generalized eigenvalues for solving the +C continuous-time algebraic Riccati equation. +C +C ARGUMENTS +C +C Input/Output Parameters +C +C ALPHAR (input) DOUBLE PRECISION +C The real part of the numerator of the current eigenvalue +C considered. +C +C ALPHAI (input) DOUBLE PRECISION +C The imaginary part of the numerator of the current +C eigenvalue considered. +C +C BETA (input) DOUBLE PRECISION +C The (real) denominator of the current eigenvalue +C considered. It is assumed that BETA <> 0 (regular case). +C +C METHOD +C +C The function value SB02OU is set to .TRUE. for an unstable +C eigenvalue and to .FALSE., otherwise. +C +C REFERENCES +C +C None. +C +C NUMERICAL ASPECTS +C +C None. +C +C CONTRIBUTOR +C +C Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Sep. 1997. +C Supersedes Release 2.0 routine SB02CW by P. Van Dooren, Philips +C Research Laboratory, Brussels, Belgium. +C +C REVISIONS +C +C - +C +C KEYWORDS +C +C Algebraic Riccati equation, closed loop system, continuous-time +C system, optimal regulator, Schur form. +C +C ****************************************************************** +C + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) +C .. Scalar Arguments .. + DOUBLE PRECISION ALPHAR, ALPHAI, BETA +C .. Executable Statements .. +C + SB02OU = ( ALPHAR.LT.ZERO .AND. BETA.LT.ZERO ) .OR. + $ ( ALPHAR.GT.ZERO .AND. BETA.GT.ZERO ) +C + RETURN +C *** Last line of SB02OU *** + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB02OV.f Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,88 @@ + LOGICAL FUNCTION SB02OV( ALPHAR, ALPHAI, BETA ) +C +C SLICOT RELEASE 5.0. +C +C Copyright (c) 2002-2010 NICONET e.V. +C +C This program is free software: you can redistribute it and/or +C modify it under the terms of the GNU General Public License as +C published by the Free Software Foundation, either version 2 of +C the License, or (at your option) any later version. +C +C This program is distributed in the hope that it will be useful, +C but WITHOUT ANY WARRANTY; without even the implied warranty of +C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +C GNU General Public License for more details. +C +C You should have received a copy of the GNU General Public License +C along with this program. If not, see +C <http://www.gnu.org/licenses/>. +C +C PURPOSE +C +C To select the unstable generalized eigenvalues for solving the +C discrete-time algebraic Riccati equation. +C +C ARGUMENTS +C +C Input/Output Parameters +C +C ALPHAR (input) DOUBLE PRECISION +C The real part of the numerator of the current eigenvalue +C considered. +C +C ALPHAI (input) DOUBLE PRECISION +C The imaginary part of the numerator of the current +C eigenvalue considered. +C +C BETA (input) DOUBLE PRECISION +C The (real) denominator of the current eigenvalue +C considered. +C +C METHOD +C +C The function value SB02OV is set to .TRUE. for an unstable +C eigenvalue (i.e., with modulus greater than or equal to one) and +C to .FALSE., otherwise. +C +C REFERENCES +C +C None. +C +C NUMERICAL ASPECTS +C +C None. +C +C CONTRIBUTOR +C +C Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Sep. 1997. +C Supersedes Release 2.0 routine SB02CX by P. Van Dooren, Philips +C Research Laboratory, Brussels, Belgium. +C +C REVISIONS +C +C - +C +C KEYWORDS +C +C Algebraic Riccati equation, closed loop system, continuous-time +C system, optimal regulator, Schur form. +C +C ****************************************************************** +C + DOUBLE PRECISION ONE + PARAMETER ( ONE = 1.0D0 ) +C .. Scalar Arguments .. + DOUBLE PRECISION ALPHAR, ALPHAI, BETA +C .. External Functions .. + DOUBLE PRECISION DLAPY2 + EXTERNAL DLAPY2 +C .. Intrinsic Functions .. + INTRINSIC ABS +C .. Executable Statements .. +C + SB02OV = DLAPY2( ALPHAR, ALPHAI ).GE.ABS( BETA ) +C + RETURN +C *** Last line of SB02OV *** + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB02OW.f Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,83 @@ + LOGICAL FUNCTION SB02OW( ALPHAR, ALPHAI, BETA ) +C +C SLICOT RELEASE 5.0. +C +C Copyright (c) 2002-2010 NICONET e.V. +C +C This program is free software: you can redistribute it and/or +C modify it under the terms of the GNU General Public License as +C published by the Free Software Foundation, either version 2 of +C the License, or (at your option) any later version. +C +C This program is distributed in the hope that it will be useful, +C but WITHOUT ANY WARRANTY; without even the implied warranty of +C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +C GNU General Public License for more details. +C +C You should have received a copy of the GNU General Public License +C along with this program. If not, see +C <http://www.gnu.org/licenses/>. +C +C PURPOSE +C +C To select the stable generalized eigenvalues for solving the +C continuous-time algebraic Riccati equation. +C +C ARGUMENTS +C +C Input/Output Parameters +C +C ALPHAR (input) DOUBLE PRECISION +C The real part of the numerator of the current eigenvalue +C considered. +C +C ALPHAI (input) DOUBLE PRECISION +C The imaginary part of the numerator of the current +C eigenvalue considered. +C +C BETA (input) DOUBLE PRECISION +C The (real) denominator of the current eigenvalue +C considered. It is assumed that BETA <> 0 (regular case). +C +C METHOD +C +C The function value SB02OW is set to .TRUE. for a stable eigenvalue +C and to .FALSE., otherwise. +C +C REFERENCES +C +C None. +C +C NUMERICAL ASPECTS +C +C None. +C +C CONTRIBUTOR +C +C Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Sep. 1997. +C Supersedes Release 2.0 routine SB02CW by P. Van Dooren, Philips +C Research Laboratory, Brussels, Belgium. +C +C REVISIONS +C +C - +C +C KEYWORDS +C +C Algebraic Riccati equation, closed loop system, continuous-time +C system, optimal regulator, Schur form. +C +C ****************************************************************** +C + DOUBLE PRECISION ZERO + PARAMETER ( ZERO = 0.0D0 ) +C .. Scalar Arguments .. + DOUBLE PRECISION ALPHAR, ALPHAI, BETA +C .. Executable Statements .. +C + SB02OW = ( ALPHAR.LT.ZERO .AND. BETA.GT.ZERO ) .OR. + $ ( ALPHAR.GT.ZERO .AND. BETA.LT.ZERO ) +C + RETURN +C *** Last line of SB02OW *** + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB02OY.f Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,791 @@ + SUBROUTINE SB02OY( TYPE, DICO, JOBB, FACT, UPLO, JOBL, JOBE, N, M, + $ P, A, LDA, B, LDB, Q, LDQ, R, LDR, L, LDL, E, + $ LDE, AF, LDAF, BF, LDBF, TOL, IWORK, DWORK, + $ LDWORK, INFO ) +C +C SLICOT RELEASE 5.0. +C +C Copyright (c) 2002-2010 NICONET e.V. +C +C This program is free software: you can redistribute it and/or +C modify it under the terms of the GNU General Public License as +C published by the Free Software Foundation, either version 2 of +C the License, or (at your option) any later version. +C +C This program is distributed in the hope that it will be useful, +C but WITHOUT ANY WARRANTY; without even the implied warranty of +C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +C GNU General Public License for more details. +C +C You should have received a copy of the GNU General Public License +C along with this program. If not, see +C <http://www.gnu.org/licenses/>. +C +C PURPOSE +C +C To construct the extended matrix pairs for the computation of the +C solution of the algebraic matrix Riccati equations arising in the +C problems of optimal control, both discrete and continuous-time, +C and of spectral factorization, both discrete and continuous-time. +C These matrix pairs, of dimension 2N + M, are given by +C +C discrete-time continuous-time +C +C |A 0 B| |E 0 0| |A 0 B| |E 0 0| +C |Q -E' L| - z |0 -A' 0|, |Q A' L| - s |0 -E' 0|. (1) +C |L' 0 R| |0 -B' 0| |L' B' R| |0 0 0| +C +C After construction, these pencils are compressed to a form +C (see [1]) +C +C lambda x A - B , +C f f +C +C where A and B are 2N-by-2N matrices. +C f f +C -1 +C Optionally, matrix G = BR B' may be given instead of B and R; +C then, for L = 0, 2N-by-2N matrix pairs are directly constructed as +C +C discrete-time continuous-time +C +C |A 0 | |E G | |A -G | |E 0 | +C | | - z | |, | | - s | |. (2) +C |Q -E'| |0 -A'| |Q A'| |0 -E'| +C +C Similar pairs are obtained for non-zero L, if SLICOT Library +C routine SB02MT is called before SB02OY. +C Other options include the case with E identity matrix, L a zero +C matrix, or Q and/or R given in a factored form, Q = C'C, R = D'D. +C For spectral factorization problems, there are minor differences +C (e.g., B is replaced by C'). +C The second matrix in (2) is not constructed in the continuous-time +C case if E is specified as being an identity matrix. +C +C ARGUMENTS +C +C Mode Parameters +C +C TYPE CHARACTER*1 +C Specifies the type of problem to be addressed as follows: +C = 'O': Optimal control problem; +C = 'S': Spectral factorization problem. +C +C DICO CHARACTER*1 +C Specifies the type of linear system considered as follows: +C = 'C': Continuous-time system; +C = 'D': Discrete-time system. +C +C JOBB CHARACTER*1 +C Specifies whether or not the matrix G is given, instead +C of the matrices B and R, as follows: +C = 'B': B and R are given; +C = 'G': G is given. +C For JOBB = 'G', a 2N-by-2N matrix pair is directly +C obtained assuming L = 0 (see the description of JOBL). +C +C FACT CHARACTER*1 +C Specifies whether or not the matrices Q and/or R (if +C JOBB = 'B') are factored, as follows: +C = 'N': Not factored, Q and R are given; +C = 'C': C is given, and Q = C'C; +C = 'D': D is given, and R = D'D (if TYPE = 'O'), or +C R = D + D' (if TYPE = 'S'); +C = 'B': Both factors C and D are given, Q = C'C, R = D'D +C (or R = D + D'). +C +C UPLO CHARACTER*1 +C If JOBB = 'G', or FACT = 'N', specifies which triangle of +C the matrices G and Q (if FACT = 'N'), or Q and R (if +C JOBB = 'B'), is stored, as follows: +C = 'U': Upper triangle is stored; +C = 'L': Lower triangle is stored. +C +C JOBL CHARACTER*1 +C Specifies whether or not the matrix L is zero, as follows: +C = 'Z': L is zero; +C = 'N': L is nonzero. +C JOBL is not used if JOBB = 'G' and JOBL = 'Z' is assumed. +C Using SLICOT Library routine SB02MT to compute the +C corresponding A and Q in this case, before calling SB02OY, +C enables to obtain 2N-by-2N matrix pairs directly. +C +C JOBE CHARACTER*1 +C Specifies whether or not the matrix E is identity, as +C follows: +C = 'I': E is the identity matrix; +C = 'N': E is a general matrix. +C +C Input/Output Parameters +C +C N (input) INTEGER +C The order of the matrices A, Q, and E, and the number +C of rows of the matrices B and L. N >= 0. +C +C M (input) INTEGER +C If JOBB = 'B', M is the order of the matrix R, and the +C number of columns of the matrix B. M >= 0. +C M is not used if JOBB = 'G'. +C +C P (input) INTEGER +C If FACT = 'C' or 'D' or 'B', or if TYPE = 'S', P is the +C number of rows of the matrix C and/or D, respectively. +C P >= 0, and if JOBB = 'B' and TYPE = 'S', then P = M. +C Otherwise, P is not used. +C +C A (input) DOUBLE PRECISION array, dimension (LDA,N) +C The leading N-by-N part of this array must contain the +C state matrix A of the system. +C +C LDA INTEGER +C The leading dimension of array A. LDA >= MAX(1,N). +C +C B (input) DOUBLE PRECISION array, dimension (LDB,*) +C If JOBB = 'B', the leading N-by-M part of this array must +C contain the input matrix B of the system. +C If JOBB = 'G', the leading N-by-N upper triangular part +C (if UPLO = 'U') or lower triangular part (if UPLO = 'L') +C of this array must contain the upper triangular part or +C lower triangular part, respectively, of the matrix +C -1 +C G = BR B'. The stricly lower triangular part (if +C UPLO = 'U') or stricly upper triangular part (if +C UPLO = 'L') is not referenced. +C +C LDB INTEGER +C The leading dimension of array B. LDB >= MAX(1,N). +C +C Q (input) DOUBLE PRECISION array, dimension (LDQ,N) +C If FACT = 'N' or 'D', the leading N-by-N upper triangular +C part (if UPLO = 'U') or lower triangular part (if UPLO = +C 'L') of this array must contain the upper triangular part +C or lower triangular part, respectively, of the symmetric +C output weighting matrix Q. The stricly lower triangular +C part (if UPLO = 'U') or stricly upper triangular part (if +C UPLO = 'L') is not referenced. +C If FACT = 'C' or 'B', the leading P-by-N part of this +C array must contain the output matrix C of the system. +C +C LDQ INTEGER +C The leading dimension of array Q. +C LDQ >= MAX(1,N) if FACT = 'N' or 'D', +C LDQ >= MAX(1,P) if FACT = 'C' or 'B'. +C +C R (input) DOUBLE PRECISION array, dimension (LDR,M) +C If FACT = 'N' or 'C', the leading M-by-M upper triangular +C part (if UPLO = 'U') or lower triangular part (if UPLO = +C 'L') of this array must contain the upper triangular part +C or lower triangular part, respectively, of the symmetric +C input weighting matrix R. The stricly lower triangular +C part (if UPLO = 'U') or stricly upper triangular part (if +C UPLO = 'L') is not referenced. +C If FACT = 'D' or 'B', the leading P-by-M part of this +C array must contain the direct transmission matrix D of the +C system. +C If JOBB = 'G', this array is not referenced. +C +C LDR INTEGER +C The leading dimension of array R. +C LDR >= MAX(1,M) if JOBB = 'B' and FACT = 'N' or 'C'; +C LDR >= MAX(1,P) if JOBB = 'B' and FACT = 'D' or 'B'; +C LDR >= 1 if JOBB = 'G'. +C +C L (input) DOUBLE PRECISION array, dimension (LDL,M) +C If JOBL = 'N' (and JOBB = 'B'), the leading N-by-M part of +C this array must contain the cross weighting matrix L. +C If JOBL = 'Z' or JOBB = 'G', this array is not referenced. +C +C LDL INTEGER +C The leading dimension of array L. +C LDL >= MAX(1,N) if JOBL = 'N'; +C LDL >= 1 if JOBL = 'Z' or JOBB = 'G'. +C +C E (input) DOUBLE PRECISION array, dimension (LDE,N) +C If JOBE = 'N', the leading N-by-N part of this array must +C contain the matrix E of the descriptor system. +C If JOBE = 'I', E is taken as identity and this array is +C not referenced. +C +C LDE INTEGER +C The leading dimension of array E. +C LDE >= MAX(1,N) if JOBE = 'N'; +C LDE >= 1 if JOBE = 'I'. +C +C AF (output) DOUBLE PRECISION array, dimension (LDAF,*) +C The leading 2N-by-2N part of this array contains the +C matrix A in the matrix pencil. +C f +C Array AF must have 2*N+M columns if JOBB = 'B', and 2*N +C columns, otherwise. +C +C LDAF INTEGER +C The leading dimension of array AF. +C LDAF >= MAX(1,2*N+M) if JOBB = 'B', +C LDAF >= MAX(1,2*N) if JOBB = 'G'. +C +C BF (output) DOUBLE PRECISION array, dimension (LDBF,2*N) +C If DICO = 'D' or JOBB = 'B' or JOBE = 'N', the leading +C 2N-by-2N part of this array contains the matrix B in the +C f +C matrix pencil. +C The last M zero columns are never constructed. +C If DICO = 'C' and JOBB = 'G' and JOBE = 'I', this array +C is not referenced. +C +C LDBF INTEGER +C The leading dimension of array BF. +C LDBF >= MAX(1,2*N+M) if JOBB = 'B', +C LDBF >= MAX(1,2*N) if JOBB = 'G' and ( DICO = 'D' or +C JOBE = 'N' ), +C LDBF >= 1 if JOBB = 'G' and ( DICO = 'C' and +C JOBE = 'I' ). +C +C Tolerances +C +C TOL DOUBLE PRECISION +C The tolerance to be used to test for near singularity of +C the original matrix pencil, specifically of the triangular +C factor obtained during the reduction process. If the user +C sets TOL > 0, then the given value of TOL is used as a +C lower bound for the reciprocal condition number of that +C matrix; a matrix whose estimated condition number is less +C than 1/TOL is considered to be nonsingular. If the user +C sets TOL <= 0, then a default tolerance, defined by +C TOLDEF = EPS, is used instead, where EPS is the machine +C precision (see LAPACK Library routine DLAMCH). +C This parameter is not referenced if JOBB = 'G'. +C +C Workspace +C +C IWORK INTEGER array, dimension (LIWORK) +C LIWORK >= M if JOBB = 'B', +C LIWORK >= 1 if JOBB = 'G'. +C +C DWORK DOUBLE PRECISION array, dimension (LDWORK) +C On exit, if INFO = 0, DWORK(1) returns the optimal value +C of LDWORK. If JOBB = 'B', DWORK(2) returns the reciprocal +C of the condition number of the M-by-M lower triangular +C matrix obtained after compression. +C +C LDWORK INTEGER +C The length of the array DWORK. +C LDWORK >= 1 if JOBB = 'G', +C LDWORK >= MAX(1,2*N + M,3*M) if JOBB = 'B'. +C For optimum performance LDWORK should be larger. +C +C Error Indicator +C +C INFO INTEGER +C = 0: successful exit; +C < 0: if INFO = -i, the i-th argument had an illegal +C value; +C = 1: if the computed extended matrix pencil is singular, +C possibly due to rounding errors. +C +C METHOD +C +C The extended matrix pairs are constructed, taking various options +C into account. If JOBB = 'B', the problem order is reduced from +C 2N+M to 2N (see [1]). +C +C REFERENCES +C +C [1] Van Dooren, P. +C A Generalized Eigenvalue Approach for Solving Riccati +C Equations. +C SIAM J. Sci. Stat. Comp., 2, pp. 121-135, 1981. +C +C [2] Mehrmann, V. +C The Autonomous Linear Quadratic Control Problem. Theory and +C Numerical Solution. +C Lect. Notes in Control and Information Sciences, vol. 163, +C Springer-Verlag, Berlin, 1991. +C +C [3] Sima, V. +C Algorithms for Linear-Quadratic Optimization. +C Pure and Applied Mathematics: A Series of Monographs and +C Textbooks, vol. 200, Marcel Dekker, Inc., New York, 1996. +C +C NUMERICAL ASPECTS +C +C The algorithm is backward stable. +C +C CONTRIBUTORS +C +C Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Sep. 1997. +C Supersedes Release 2.0 routine SB02CY by T.G.J. Beelen, Philips, +C Eindhoven, Holland, M. Vanbegin, and P. Van Dooren, Philips +C Research Laboratory, Brussels, Belgium. +C +C REVISIONS +C +C V. Sima, Research Institute for Informatics, Bucharest, Dec. 2002. +C +C KEYWORDS +C +C Algebraic Riccati equation, closed loop system, continuous-time +C system, discrete-time system, optimal regulator, Schur form. +C +C ****************************************************************** +C + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 ) +C .. Scalar Arguments .. + CHARACTER DICO, FACT, JOBB, JOBE, JOBL, TYPE, UPLO + INTEGER INFO, LDA, LDAF, LDB, LDBF, LDE, LDL, LDQ, LDR, + $ LDWORK, M, N, P + DOUBLE PRECISION TOL +C .. Array Arguments .. + INTEGER IWORK(*) + DOUBLE PRECISION A(LDA,*), AF(LDAF,*), B(LDB,*), BF(LDBF,*), + $ DWORK(*), E(LDE,*), L(LDL,*), Q(LDQ,*), R(LDR,*) +C .. Local Scalars .. + LOGICAL DISCR, LFACB, LFACN, LFACQ, LFACR, LJOBB, LJOBE, + $ LJOBL, LUPLO, OPTC + INTEGER I, ITAU, J, JWORK, N2, N2P1, NM, NNM, NP1, + $ WRKOPT + DOUBLE PRECISION RCOND, TOLDEF +C .. External Functions .. + LOGICAL LSAME + DOUBLE PRECISION DLAMCH + EXTERNAL DLAMCH, LSAME +C .. External Subroutines .. + EXTERNAL DCOPY, DGEQLF, DLACPY, DLASET, DORMQL, DSYRK, + $ DTRCON, XERBLA +C .. Intrinsic Functions .. + INTRINSIC INT, MAX +C .. Executable Statements .. +C + INFO = 0 + OPTC = LSAME( TYPE, 'O' ) + DISCR = LSAME( DICO, 'D' ) + LJOBB = LSAME( JOBB, 'B' ) + LFACN = LSAME( FACT, 'N' ) + LFACQ = LSAME( FACT, 'C' ) + LFACR = LSAME( FACT, 'D' ) + LFACB = LSAME( FACT, 'B' ) + LUPLO = LSAME( UPLO, 'U' ) + LJOBE = LSAME( JOBE, 'I' ) + N2 = N + N + IF ( LJOBB ) THEN + LJOBL = LSAME( JOBL, 'Z' ) + NM = N + M + NNM = N2 + M + ELSE + NM = N + NNM = N2 + END IF + NP1 = N + 1 + N2P1 = N2 + 1 +C +C Test the input scalar arguments. +C + IF( .NOT.OPTC .AND. .NOT.LSAME( TYPE, 'S' ) ) THEN + INFO = -1 + ELSE IF( .NOT.DISCR .AND. .NOT.LSAME( DICO, 'C' ) ) THEN + INFO = -2 + ELSE IF( .NOT.LJOBB .AND. .NOT.LSAME( JOBB, 'G' ) ) THEN + INFO = -3 + ELSE IF( .NOT.LFACQ .AND. .NOT.LFACR .AND. .NOT.LFACB + $ .AND. .NOT.LFACN ) THEN + INFO = -4 + ELSE IF( .NOT.LJOBB .OR. LFACN ) THEN + IF( .NOT.LUPLO .AND. .NOT.LSAME( UPLO, 'L' ) ) + $ INFO = -5 + ELSE IF( LJOBB ) THEN + IF( .NOT.LJOBL .AND. .NOT.LSAME( JOBL, 'N' ) ) + $ INFO = -6 + ELSE IF( .NOT.LJOBE .AND. .NOT.LSAME( JOBE, 'N' ) ) THEN + INFO = -7 + ELSE IF( N.LT.0 ) THEN + INFO = -8 + ELSE IF( LJOBB ) THEN + IF( M.LT.0 ) + $ INFO = -9 + ELSE IF( .NOT.LFACN .OR. .NOT.OPTC ) THEN + IF( P.LT.0 ) THEN + INFO = -10 + ELSE IF( LJOBB ) THEN + IF( .NOT.OPTC .AND. P.NE.M ) + $ INFO = -10 + END IF + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -12 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -14 + ELSE IF( ( ( LFACN.OR.LFACR ) .AND. LDQ.LT.MAX( 1, N ) ) .OR. + $ ( ( LFACQ.OR.LFACB ) .AND. LDQ.LT.MAX( 1, P ) ) ) THEN + INFO = -16 + ELSE IF( LDR.LT.1 ) THEN + INFO = -18 + ELSE IF( LJOBB ) THEN + IF ( ( LFACN.OR.LFACQ ) .AND. LDR.LT.M .OR. + $ ( LFACR.OR.LFACB ) .AND. LDR.LT.P ) THEN + INFO = -18 + ELSE IF( ( .NOT.LJOBL .AND. LDL.LT.MAX( 1, N ) ) .OR. + $ ( LJOBL .AND. LDL.LT.1 ) ) THEN + INFO = -20 + END IF + END IF + IF( ( .NOT.LJOBE .AND. LDE.LT.MAX( 1, N ) ) .OR. + $ ( LJOBE .AND. LDE.LT.1 ) ) THEN + INFO = -22 + ELSE IF( LDAF.LT.MAX( 1, NNM ) ) THEN + INFO = -24 + ELSE IF( ( ( LJOBB .OR. DISCR .OR. .NOT.LJOBE ) .AND. + $ LDBF.LT.NNM ) .OR. ( LDBF.LT.1 ) ) THEN + INFO = -26 + ELSE IF( ( LJOBB .AND. LDWORK.LT.MAX( NNM, 3*M ) ) .OR. + $ LDWORK.LT.1 ) THEN + INFO = -30 + END IF +C + IF ( INFO.NE.0 ) THEN +C +C Error return. +C + CALL XERBLA( 'SB02OY', -INFO ) + RETURN + END IF +C +C Quick return if possible. +C + DWORK(1) = ONE + IF ( N.EQ.0 ) + $ RETURN +C +C Construct the extended matrices in AF and BF, by block-columns. +C + CALL DLACPY( 'Full', N, N, A, LDA, AF, LDAF ) +C + IF ( .NOT.LFACQ .AND. .NOT.LFACB ) THEN + CALL DLACPY( UPLO, N, N, Q, LDQ, AF(NP1,1), LDAF ) + IF ( LUPLO ) THEN +C +C Construct the lower triangle of Q. +C + DO 20 J = 1, N - 1 + CALL DCOPY( N-J, Q(J,J+1), LDQ, AF(NP1+J,J), 1 ) + 20 CONTINUE +C + ELSE +C +C Construct the upper triangle of Q. +C + DO 40 J = 2, N + CALL DCOPY( J-1, Q(J,1), LDQ, AF(NP1,J), 1 ) + 40 CONTINUE +C + END IF + ELSE + CALL DSYRK( 'Upper', 'Transpose', N, P, ONE, Q, LDQ, ZERO, + $ AF(NP1,1), LDAF ) +C + DO 60 J = 2, N + CALL DCOPY( J-1, AF(NP1,J), 1, AF(N+J,1), LDAF ) + 60 CONTINUE +C + END IF +C + IF ( LJOBB ) THEN + IF ( LJOBL ) THEN + CALL DLASET( 'Full', M, N, ZERO, ZERO, AF(N2P1,1), LDAF ) + ELSE +C + DO 80 I = 1, N + CALL DCOPY( M, L(I,1), LDL, AF(N2P1,I), 1 ) + 80 CONTINUE +C + END IF + END IF +C + IF ( DISCR.OR.LJOBB ) THEN + CALL DLASET( 'Full', N, N, ZERO, ZERO, AF(1,NP1), LDAF ) + ELSE + IF ( LUPLO ) THEN +C +C Construct (1,2) block of AF using the upper triangle of G. +C + DO 140 J = 1, N +C + DO 100 I = 1, J + AF(I,N+J)= -B(I,J) + 100 CONTINUE +C + DO 120 I = J + 1, N + AF(I,N+J)= -B(J,I) + 120 CONTINUE +C + 140 CONTINUE +C + ELSE +C +C Construct (1,2) block of AF using the lower triangle of G. +C + DO 200 J = 1, N +C + DO 160 I = 1, J - 1 + AF(I,N+J)= -B(J,I) + 160 CONTINUE +C + DO 180 I = J, N + AF(I,N+J)= -B(I,J) + 180 CONTINUE +C + 200 CONTINUE +C + END IF + END IF +C + IF ( DISCR ) THEN + IF ( LJOBE ) THEN + CALL DLASET( 'Full', NM, N, ZERO, -ONE, AF(NP1,NP1), LDAF ) + ELSE +C + DO 240 J = 1, N +C + DO 220 I = 1, N + AF(N+I,N+J)= -E(J,I) + 220 CONTINUE +C + 240 CONTINUE +C + IF ( LJOBB ) + $ CALL DLASET( 'Full', M, N, ZERO, ZERO, AF(N2P1,NP1), + $ LDAF ) + END IF + ELSE +C + DO 280 J = 1, N +C + DO 260 I = 1, N + AF(N+I,N+J)= A(J,I) + 260 CONTINUE +C + 280 CONTINUE +C + IF ( LJOBB ) THEN + IF ( OPTC ) THEN +C + DO 300 J = 1, N + CALL DCOPY ( M, B(J,1), LDB, AF(N2P1,N+J), 1 ) + 300 CONTINUE +C + ELSE + CALL DLACPY( 'Full', P, N, Q, LDQ, AF(N2P1,NP1), LDAF ) + END IF + END IF + END IF +C + IF ( LJOBB ) THEN +C + IF ( OPTC ) THEN + CALL DLACPY( 'Full', N, M, B, LDB, AF(1,N2P1), LDAF ) + ELSE +C + DO 320 I = 1, P + CALL DCOPY( N, Q(I,1), LDQ, AF(1,N2+I), 1 ) + 320 CONTINUE +C + END IF +C + IF ( LJOBL ) THEN + CALL DLASET( 'Full', N, M, ZERO, ZERO, AF(NP1,N2P1), LDAF ) + ELSE + CALL DLACPY( 'Full', N, M, L, LDL, AF(NP1,N2P1), LDAF ) + END IF +C + IF ( .NOT.LFACR .AND. .NOT.LFACB ) THEN + CALL DLACPY( UPLO, M, M, R, LDR, AF(N2P1,N2P1), LDAF ) + IF ( LUPLO ) THEN +C +C Construct the lower triangle of R. +C + DO 340 J = 1, M - 1 + CALL DCOPY( M-J, R(J,J+1), LDR, AF(N2P1+J,N2+J), 1 ) + 340 CONTINUE +C + ELSE +C +C Construct the upper triangle of R. +C + DO 360 J = 2, M + CALL DCOPY( J-1, R(J,1), LDR, AF(N2P1,N2+J), 1 ) + 360 CONTINUE +C + END IF + ELSE IF ( OPTC ) THEN + CALL DSYRK( 'Upper', 'Transpose', M, P, ONE, R, LDR, ZERO, + $ AF(N2P1,N2P1), LDAF ) +C + DO 380 J = 2, M + CALL DCOPY( J-1, AF(N2P1,N2+J), 1, AF(N2+J,N2P1), LDAF ) + 380 CONTINUE +C + ELSE +C + DO 420 J = 1, M +C + DO 400 I = 1, P + AF(N2+I,N2+J) = R(I,J) + R(J,I) + 400 CONTINUE +C + 420 CONTINUE +C + END IF + END IF +C + IF ( .NOT.LJOBB .AND. .NOT.DISCR .AND. LJOBE ) + $ RETURN +C +C Construct the first two block columns of BF. +C + IF ( LJOBE ) THEN + CALL DLASET( 'Full', N+NM, N, ZERO, ONE, BF, LDBF ) + ELSE + CALL DLACPY( 'Full', N, N, E, LDE, BF, LDBF ) + CALL DLASET( 'Full', NM, N, ZERO, ZERO, BF(NP1,1), LDBF ) + END IF +C + IF ( .NOT.DISCR.OR.LJOBB ) THEN + CALL DLASET( 'Full', N, N, ZERO, ZERO, BF(1,NP1), LDBF ) + ELSE + IF ( LUPLO ) THEN +C +C Construct (1,2) block of BF using the upper triangle of G. +C + DO 480 J = 1, N +C + DO 440 I = 1, J + BF(I,N+J)= B(I,J) + 440 CONTINUE +C + DO 460 I = J + 1, N + BF(I,N+J)= B(J,I) + 460 CONTINUE +C + 480 CONTINUE +C + ELSE +C +C Construct (1,2) block of BF using the lower triangle of G. +C + DO 540 J = 1, N +C + DO 500 I = 1, J - 1 + BF(I,N+J)= B(J,I) + 500 CONTINUE +C + DO 520 I = J, N + BF(I,N+J)= B(I,J) + 520 CONTINUE +C + 540 CONTINUE +C + END IF + END IF +C + IF ( DISCR ) THEN +C + DO 580 J = 1, N +C + DO 560 I = 1, N + BF(N+I,N+J)= -A(J,I) + 560 CONTINUE +C + 580 CONTINUE +C + IF ( LJOBB ) THEN +C + IF ( OPTC ) THEN +C + DO 620 J = 1, N +C + DO 600 I = 1, M + BF(N2+I,N+J)= -B(J,I) + 600 CONTINUE +C + 620 CONTINUE +C + ELSE +C + DO 660 J = 1, N +C + DO 640 I = 1, P + BF(N2+I,N+J) = -Q(I,J) + 640 CONTINUE +C + 660 CONTINUE +C + END IF + END IF +C + ELSE + IF ( LJOBE ) THEN + CALL DLASET( 'Full', NM, N, ZERO, -ONE, BF(NP1,NP1), LDBF ) + ELSE +C + DO 700 J = 1, N +C + DO 680 I = 1, N + BF(N+I,N+J)= -E(J,I) + 680 CONTINUE +C + 700 CONTINUE +C + IF ( LJOBB ) + $ CALL DLASET( 'Full', M, N, ZERO, ZERO, BF(N2P1,NP1), + $ LDBF ) + END IF + END IF +C + IF ( .NOT.LJOBB ) + $ RETURN +C +C Compress the pencil lambda x BF - AF, using QL factorization. +C (Note: Comments in the code beginning "Workspace:" describe the +C minimal amount of real workspace needed at that point in the +C code, as well as the preferred amount for good performance. +C NB refers to the optimal block size for the immediately +C following subroutine, as returned by ILAENV.) +C +C Workspace: need 2*M; prefer M + M*NB. +C + ITAU = 1 + JWORK = ITAU + M + CALL DGEQLF( NNM, M, AF(1,N2P1), LDAF, DWORK(ITAU), DWORK(JWORK), + $ LDWORK-JWORK+1, INFO ) + WRKOPT = DWORK(JWORK) +C +C Workspace: need 2*N+M; prefer M + 2*N*NB. +C + CALL DORMQL( 'Left', 'Transpose', NNM, N2, M, AF(1,N2P1), LDAF, + $ DWORK(ITAU), AF, LDAF, DWORK(JWORK), LDWORK-JWORK+1, + $ INFO ) + WRKOPT = MAX( WRKOPT, INT( DWORK(JWORK) )+JWORK-1 ) +C + CALL DORMQL( 'Left', 'Transpose', NNM, N2, M, AF(1,N2P1), LDAF, + $ DWORK(ITAU), BF, LDBF, DWORK(JWORK), LDWORK-JWORK+1, + $ INFO ) +C +C Check the singularity of the L factor in the QL factorization: +C if singular, then the extended matrix pencil is also singular. +C Workspace 3*M. +C + TOLDEF = TOL + IF ( TOLDEF.LE.ZERO ) + $ TOLDEF = DLAMCH( 'Epsilon' ) +C + CALL DTRCON( '1-norm', 'Lower', 'Non unit', M, AF(N2P1,N2P1), + $ LDAF, RCOND, DWORK, IWORK, INFO ) + WRKOPT = MAX( WRKOPT, 3*M ) +C + IF ( RCOND.LE.TOLDEF ) + $ INFO = 1 +C + DWORK(1) = WRKOPT + DWORK(2) = RCOND +C + RETURN +C *** Last line of SB02OY *** + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB10ID.dat Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,21 @@ + SB10ID EXAMPLE PROGRAM DATA + 6 2 3 + -1.0 0.0 4.0 5.0 -3.0 -2.0 + -2.0 4.0 -7.0 -2.0 0.0 3.0 + -6.0 9.0 -5.0 0.0 2.0 -1.0 + -8.0 4.0 7.0 -1.0 -3.0 0.0 + 2.0 5.0 8.0 -9.0 1.0 -4.0 + 3.0 -5.0 8.0 0.0 2.0 -6.0 + -3.0 -4.0 + 2.0 0.0 + -5.0 -7.0 + 4.0 -6.0 + -3.0 9.0 + 1.0 -2.0 + 1.0 -1.0 2.0 -4.0 0.0 -3.0 + -3.0 0.0 5.0 -1.0 1.0 1.0 + -7.0 5.0 0.0 -8.0 2.0 -2.0 + 1.0 -2.0 + 0.0 4.0 + 5.0 -3.0 + 1.0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB10ID.res Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,32 @@ + SB10ID EXAMPLE PROGRAM RESULTS + + + The controller state matrix AK is + + -39.0671 9.9293 22.2322 -27.4113 43.8655 + -6.6117 3.0006 11.0878 -11.4130 15.4269 + 33.6805 -6.6934 -23.9953 14.1438 -33.4358 + -32.3191 9.7316 25.4033 -24.0473 42.0517 + -44.1655 18.7767 34.8873 -42.4369 50.8437 + + The controller input matrix BK is + + -10.2905 -16.5382 -10.9782 + -4.3598 -8.7525 -5.1447 + 6.5962 1.8975 6.2316 + -9.8770 -14.7041 -11.8778 + -9.6726 -22.7309 -18.2692 + + The controller output matrix CK is + + -0.6647 -0.0599 -1.0376 0.5619 1.7297 + -8.4202 3.9573 7.3094 -7.6283 10.6768 + + The controller matrix DK is + + 0.8466 0.4979 -0.6993 + -1.2226 -4.8689 -4.5056 + + The estimated condition numbers are + + 0.13861D-01 0.90541D-02
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB10KD.dat Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,17 @@ + SB10KD EXAMPLE PROGRAM DATA + 6 2 2 + 0.2 0.0 0.3 0.0 -0.3 -0.1 + -0.3 0.2 -0.4 -0.3 0.0 0.0 + -0.1 0.1 -0.1 0.0 0.0 -0.3 + 0.1 0.0 0.0 -0.1 -0.1 0.0 + 0.0 0.3 0.6 0.2 0.1 -0.4 + 0.2 -0.4 0.0 0.0 0.2 -0.2 + -1.0 -2.0 + 1.0 3.0 + -3.0 -4.0 + 1.0 -2.0 + 0.0 1.0 + 1.0 5.0 + 1.0 -1.0 2.0 -2.0 0.0 -3.0 + -3.0 0.0 1.0 -1.0 1.0 -1.0 + 1.1
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB10KD.f Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,650 @@ + SUBROUTINE SB10KD( N, M, NP, A, LDA, B, LDB, C, LDC, FACTOR, + $ AK, LDAK, BK, LDBK, CK, LDCK, DK, LDDK, RCOND, + $ IWORK, DWORK, LDWORK, BWORK, INFO ) +C +C SLICOT RELEASE 5.0. +C +C Copyright (c) 2002-2010 NICONET e.V. +C +C This program is free software: you can redistribute it and/or +C modify it under the terms of the GNU General Public License as +C published by the Free Software Foundation, either version 2 of +C the License, or (at your option) any later version. +C +C This program is distributed in the hope that it will be useful, +C but WITHOUT ANY WARRANTY; without even the implied warranty of +C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +C GNU General Public License for more details. +C +C You should have received a copy of the GNU General Public License +C along with this program. If not, see +C <http://www.gnu.org/licenses/>. +C +C PURPOSE +C +C To compute the matrices of the positive feedback controller +C +C | Ak | Bk | +C K = |----|----| +C | Ck | Dk | +C +C for the shaped plant +C +C | A | B | +C G = |---|---| +C | C | 0 | +C +C in the Discrete-Time Loop Shaping Design Procedure. +C +C ARGUMENTS +C +C Input/Output Parameters +C +C N (input) INTEGER +C The order of the plant. N >= 0. +C +C M (input) INTEGER +C The column size of the matrix B. M >= 0. +C +C NP (input) INTEGER +C The row size of the matrix C. NP >= 0. +C +C A (input) DOUBLE PRECISION array, dimension (LDA,N) +C The leading N-by-N part of this array must contain the +C system state matrix A of the shaped plant. +C +C LDA INTEGER +C The leading dimension of the array A. LDA >= max(1,N). +C +C B (input) DOUBLE PRECISION array, dimension (LDB,M) +C The leading N-by-M part of this array must contain the +C system input matrix B of the shaped plant. +C +C LDB INTEGER +C The leading dimension of the array B. LDB >= max(1,N). +C +C C (input) DOUBLE PRECISION array, dimension (LDC,N) +C The leading NP-by-N part of this array must contain the +C system output matrix C of the shaped plant. +C +C LDC INTEGER +C The leading dimension of the array C. LDC >= max(1,NP). +C +C FACTOR (input) DOUBLE PRECISION +C = 1 implies that an optimal controller is required; +C > 1 implies that a suboptimal controller is required +C achieving a performance FACTOR less than optimal. +C FACTOR >= 1. +C +C AK (output) DOUBLE PRECISION array, dimension (LDAK,N) +C The leading N-by-N part of this array contains the +C controller state matrix Ak. +C +C LDAK INTEGER +C The leading dimension of the array AK. LDAK >= max(1,N). +C +C BK (output) DOUBLE PRECISION array, dimension (LDBK,NP) +C The leading N-by-NP part of this array contains the +C controller input matrix Bk. +C +C LDBK INTEGER +C The leading dimension of the array BK. LDBK >= max(1,N). +C +C CK (output) DOUBLE PRECISION array, dimension (LDCK,N) +C The leading M-by-N part of this array contains the +C controller output matrix Ck. +C +C LDCK INTEGER +C The leading dimension of the array CK. LDCK >= max(1,M). +C +C DK (output) DOUBLE PRECISION array, dimension (LDDK,NP) +C The leading M-by-NP part of this array contains the +C controller matrix Dk. +C +C LDDK INTEGER +C The leading dimension of the array DK. LDDK >= max(1,M). +C +C RCOND (output) DOUBLE PRECISION array, dimension (4) +C RCOND(1) contains an estimate of the reciprocal condition +C number of the linear system of equations from +C which the solution of the P-Riccati equation is +C obtained; +C RCOND(2) contains an estimate of the reciprocal condition +C number of the linear system of equations from +C which the solution of the Q-Riccati equation is +C obtained; +C RCOND(3) contains an estimate of the reciprocal condition +C number of the linear system of equations from +C which the solution of the X-Riccati equation is +C obtained; +C RCOND(4) contains an estimate of the reciprocal condition +C number of the matrix Rx + Bx'*X*Bx (see the +C comments in the code). +C +C Workspace +C +C IWORK INTEGER array, dimension 2*max(N,NP+M) +C +C DWORK DOUBLE PRECISION array, dimension (LDWORK) +C On exit, if INFO = 0, DWORK(1) contains the optimal value +C of LDWORK. +C +C LDWORK INTEGER +C The dimension of the array DWORK. +C LDWORK >= 15*N*N + 6*N + +C max( 14*N+23, 16*N, 2*N+NP+M, 3*(NP+M) ) + +C max( N*N, 11*N*NP + 2*M*M + 8*NP*NP + 8*M*N + +C 4*M*NP + NP ). +C For good performance, LDWORK must generally be larger. +C +C BWORK LOGICAL array, dimension (2*N) +C +C Error Indicator +C +C INFO INTEGER +C = 0: successful exit; +C < 0: if INFO = -i, the i-th argument had an illegal +C value; +C = 1: the P-Riccati equation is not solved successfully; +C = 2: the Q-Riccati equation is not solved successfully; +C = 3: the X-Riccati equation is not solved successfully; +C = 4: the iteration to compute eigenvalues failed to +C converge; +C = 5: the matrix Rx + Bx'*X*Bx is singular; +C = 6: the closed-loop system is unstable. +C +C METHOD +C +C The routine implements the method presented in [1]. +C +C REFERENCES +C +C [1] McFarlane, D. and Glover, K. +C A loop shaping design procedure using H_infinity synthesis. +C IEEE Trans. Automat. Control, vol. AC-37, no. 6, pp. 759-769, +C 1992. +C +C NUMERICAL ASPECTS +C +C The accuracy of the results depends on the conditioning of the +C two Riccati equations solved in the controller design. For +C better conditioning it is advised to take FACTOR > 1. +C +C CONTRIBUTORS +C +C P.Hr. Petkov, D.W. Gu and M.M. Konstantinov, October 2000. +C +C REVISIONS +C +C V. Sima, Katholieke University Leuven, January 2001, +C February 2001. +C +C KEYWORDS +C +C H_infinity control, Loop-shaping design, Robust control. +C +C ****************************************************************** +C +C .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) +C .. +C .. Scalar Arguments .. + INTEGER INFO, LDA, LDAK, LDB, LDBK, LDC, LDCK, LDDK, + $ LDWORK, M, N, NP + DOUBLE PRECISION FACTOR +C .. +C .. Array Arguments .. + INTEGER IWORK( * ) + LOGICAL BWORK( * ) + DOUBLE PRECISION A( LDA, * ), AK( LDAK, * ), B( LDB, * ), + $ BK( LDBK, * ), C( LDC, * ), CK( LDCK, * ), + $ DK( LDDK, * ), DWORK( * ), RCOND( 4 ) +C .. +C .. Local Scalars .. + INTEGER I, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, + $ I11, I12, I13, I14, I15, I16, I17, I18, I19, + $ I20, I21, I22, I23, I24, I25, I26, INFO2, + $ IWRK, J, LWA, LWAMAX, MINWRK, N2, NS, SDIM + DOUBLE PRECISION GAMMA, RNORM +C .. +C .. External Functions .. + LOGICAL SELECT + DOUBLE PRECISION DLANSY, DLAPY2 + EXTERNAL DLANSY, DLAPY2, SELECT +C .. +C .. External Subroutines .. + EXTERNAL DGEMM, DGEES, DLACPY, DLASET, DPOTRF, DPOTRS, + $ DSYCON, DSYEV, DSYRK, DSYTRF, DSYTRS, SB02OD, + $ XERBLA +C .. +C .. Intrinsic Functions .. + INTRINSIC DBLE, INT, MAX, SQRT +C .. +C .. Executable Statements .. +C +C Decode and Test input parameters. +C + INFO = 0 + IF( N.LT.0 ) THEN + INFO = -1 + ELSE IF( M.LT.0 ) THEN + INFO = -2 + ELSE IF( NP.LT.0 ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -5 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -7 + ELSE IF( LDC.LT.MAX( 1, NP ) ) THEN + INFO = -9 + ELSE IF( FACTOR.LT.ONE ) THEN + INFO = -10 + ELSE IF( LDAK.LT.MAX( 1, N ) ) THEN + INFO = -12 + ELSE IF( LDBK.LT.MAX( 1, N ) ) THEN + INFO = -14 + ELSE IF( LDCK.LT.MAX( 1, M ) ) THEN + INFO = -16 + ELSE IF( LDDK.LT.MAX( 1, M ) ) THEN + INFO = -18 + END IF +C +C Compute workspace. +C + MINWRK = 15*N*N + 6*N + MAX( 14*N+23, 16*N, 2*N+NP+M, 3*(NP+M) ) + + $ MAX( N*N, 11*N*NP + 2*M*M + 8*NP*NP + 8*M*N + + $ 4*M*NP + NP ) + IF( LDWORK.LT.MINWRK ) THEN + INFO = -22 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'SB10KD', -INFO ) + RETURN + END IF +C +C Quick return if possible. +C + IF( N.EQ.0 .OR. M.EQ.0 .OR. NP.EQ.0 ) THEN + RCOND( 1 ) = ONE + RCOND( 2 ) = ONE + RCOND( 3 ) = ONE + RCOND( 4 ) = ONE + DWORK( 1 ) = ONE + RETURN + END IF +C +C Workspace usage. +C + N2 = 2*N + I1 = N*N + I2 = I1 + N*N + I3 = I2 + N*N + I4 = I3 + N*N + I5 = I4 + N2 + I6 = I5 + N2 + I7 = I6 + N2 + I8 = I7 + N2*N2 + I9 = I8 + N2*N2 +C + IWRK = I9 + N2*N2 + LWAMAX = 0 +C +C Compute Cr = C'*C . +C + CALL DSYRK( 'U', 'T', N, NP, ONE, C, LDC, ZERO, DWORK( I2+1 ), N ) +C +C Compute Dr = B*B' . +C + CALL DSYRK( 'U', 'N', N, M, ONE, B, LDB, ZERO, DWORK( I3+1 ), N ) +C -1 +C Solution of the Riccati equation A'*P*(In + Dr*P) *A - P + Cr = 0. +C + CALL SB02OD( 'D', 'G', 'N', 'U', 'Z', 'S', N, M, NP, A, LDA, + $ DWORK( I3+1 ), N, DWORK( I2+1 ), N, DWORK, M, DWORK, + $ N, RCOND( 1 ), DWORK, N, DWORK( I4+1 ), + $ DWORK( I5+1 ), DWORK( I6+1 ), DWORK( I7+1 ), N2, + $ DWORK( I8+1 ), N2, DWORK( I9+1 ), N2, -ONE, IWORK, + $ DWORK( IWRK+1 ), LDWORK-IWRK, BWORK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 1 + RETURN + END IF + LWA = INT( DWORK( IWRK+1 ) ) + IWRK + LWAMAX = MAX( LWA, LWAMAX ) +C +C Transpose A in AK (used as workspace). +C + DO 40 J = 1, N + DO 30 I = 1, N + AK( I,J ) = A( J,I ) + 30 CONTINUE + 40 CONTINUE +C -1 +C Solution of the Riccati equation A*Q*(In + Cr*Q) *A' - Q + Dr = 0. +C + CALL SB02OD( 'D', 'G', 'N', 'U', 'Z', 'S', N, M, NP, AK, LDAK, + $ DWORK( I2+1 ), N, DWORK( I3+1 ), N, DWORK, M, DWORK, + $ N, RCOND( 2 ), DWORK( I1+1 ), N, DWORK( I4+1 ), + $ DWORK( I5+1 ), DWORK( I6+1 ), DWORK( I7+1 ), N2, + $ DWORK( I8+1 ), N2, DWORK( I9+1 ), N2, -ONE, IWORK, + $ DWORK( IWRK+1 ), LDWORK-IWRK, BWORK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 2 + RETURN + END IF + LWA = INT( DWORK( IWRK+1 ) ) + IWRK + LWAMAX = MAX( LWA, LWAMAX ) +C +C Compute gamma. +C + CALL DGEMM( 'N', 'N', N, N, N, ONE, DWORK( I1+1 ), N, DWORK, N, + $ ZERO, AK, LDAK ) + CALL DGEES( 'N', 'N', SELECT, N, AK, LDAK, SDIM, DWORK( I6+1 ), + $ DWORK( I7+1 ), DWORK( IWRK+1 ), N, DWORK( IWRK+1 ), + $ LDWORK-IWRK, BWORK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 4 + RETURN + END IF + LWA = INT( DWORK( IWRK+1 ) ) + IWRK + LWAMAX = MAX( LWA, LWAMAX ) + GAMMA = ZERO + DO 50 I = 1, N + GAMMA = MAX( GAMMA, DWORK( I6+I ) ) + 50 CONTINUE + GAMMA = FACTOR*SQRT( ONE + GAMMA ) +C +C Workspace usage. +C + I3 = I2 + N*NP + I4 = I3 + NP*NP + I5 = I4 + NP*NP + I6 = I5 + NP*NP + I7 = I6 + NP + I8 = I7 + NP*NP + I9 = I8 + NP*NP + I10 = I9 + NP*NP + I11 = I10 + N*NP + I12 = I11 + N*NP + I13 = I12 + ( NP+M )*( NP+M ) + I14 = I13 + N*( NP+M ) + I15 = I14 + N*( NP+M ) + I16 = I15 + N*N + I17 = I16 + N2 + I18 = I17 + N2 + I19 = I18 + N2 + I20 = I19 + ( N2+NP+M )*( N2+NP+M ) + I21 = I20 + ( N2+NP+M )*N2 +C + IWRK = I21 + N2*N2 +C +C Compute Q*C' . +C + CALL DGEMM( 'N', 'T', N, NP, N, ONE, DWORK( I1+1 ), N, C, LDC, + $ ZERO, DWORK( I2+1 ), N ) +C +C Compute Ip + C*Q*C' . +C + CALL DLASET( 'Full', NP, NP, ZERO, ONE, DWORK( I3+1 ), NP ) + CALL DGEMM( 'N', 'N', NP, NP, N, ONE, C, LDC, DWORK( I2+1 ), N, + $ ONE, DWORK( I3+1 ), NP ) +C +C Compute the eigenvalues and eigenvectors of Ip + C'*Q*C +C + CALL DLACPY( 'U', NP, NP, DWORK( I3+1 ), NP, DWORK( I5+1 ), NP ) + CALL DSYEV( 'V', 'U', NP, DWORK( I5+1 ), NP, DWORK( I6+1 ), + $ DWORK( IWRK+1 ), LDWORK-IWRK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 4 + RETURN + END IF + LWA = INT( DWORK( IWRK+1 ) ) + IWRK + LWAMAX = MAX( LWA, LWAMAX ) +C -1 +C Compute ( Ip + C'*Q*C ) . +C + DO 70 J = 1, NP + DO 60 I = 1, NP + DWORK( I9+I+(J-1)*NP ) = DWORK( I5+J+(I-1)*NP ) / + $ DWORK( I6+I ) + 60 CONTINUE + 70 CONTINUE + CALL DGEMM( 'N', 'N', NP, NP, NP, ONE, DWORK( I5+1 ), NP, + $ DWORK( I9+1 ), NP, ZERO, DWORK( I4+1 ), NP ) +C +C Compute Z2 . +C + DO 90 J = 1, NP + DO 80 I = 1, NP + DWORK( I9+I+(J-1)*NP ) = DWORK( I5+J+(I-1)*NP ) / + $ SQRT( DWORK( I6+I ) ) + 80 CONTINUE + 90 CONTINUE + CALL DGEMM( 'N', 'N', NP, NP, NP, ONE, DWORK( I5+1 ), NP, + $ DWORK( I9+1 ), NP, ZERO, DWORK( I7+1 ), NP ) +C -1 +C Compute Z2 . +C + DO 110 J = 1, NP + DO 100 I = 1, NP + DWORK( I9+I+(J-1)*NP ) = DWORK( I5+J+(I-1)*NP )* + $ SQRT( DWORK( I6+I ) ) + 100 CONTINUE + 110 CONTINUE + CALL DGEMM( 'N', 'N', NP, NP, NP, ONE, DWORK( I5+1 ), NP, + $ DWORK( I9+1 ), NP, ZERO, DWORK( I8+1 ), NP ) +C +C Compute A*Q*C' . +C + CALL DGEMM( 'N', 'N', N, NP, N, ONE, A, LDA, DWORK( I2+1 ), N, + $ ZERO, DWORK( I10+1 ), N ) +C -1 +C Compute H = -A*Q*C'*( Ip + C*Q*C' ) . +C + CALL DGEMM( 'N', 'N', N, NP, NP, -ONE, DWORK( I10+1 ), N, + $ DWORK( I4+1 ), NP, ZERO, DWORK( I11+1 ), N ) +C +C Compute Rx . +C + CALL DLASET( 'F', NP+M, NP+M, ZERO, ONE, DWORK( I12+1 ), NP+M ) + DO 130 J = 1, NP + DO 120 I = 1, NP + DWORK( I12+I+(J-1)*(NP+M) ) = DWORK( I3+I+(J-1)*NP ) + 120 CONTINUE + DWORK( I12+J+(J-1)*(NP+M) ) = DWORK( I3+J+(J-1)*NP ) - + $ GAMMA*GAMMA + 130 CONTINUE +C +C Compute Bx . +C + CALL DGEMM( 'N', 'N', N, NP, NP, -ONE, DWORK( I11+1 ), N, + $ DWORK( I8+1 ), NP, ZERO, DWORK( I13+1 ), N ) + DO 150 J = 1, M + DO 140 I = 1, N + DWORK( I13+N*NP+I+(J-1)*N ) = B( I, J ) + 140 CONTINUE + 150 CONTINUE +C +C Compute Sx . +C + CALL DGEMM( 'T', 'N', N, NP, NP, ONE, C, LDC, DWORK( I8+1 ), NP, + $ ZERO, DWORK( I14+1 ), N ) + CALL DLASET( 'F', N, M, ZERO, ZERO, DWORK( I14+N*NP+1 ), N ) +C +C Solve the Riccati equation +C -1 +C X = A'*X*A + Cx - (Sx + A'*X*Bx)*(Rx + Bx'*X*B ) *(Sx'+Bx'*X*A). +C + CALL SB02OD( 'D', 'B', 'C', 'U', 'N', 'S', N, NP+M, NP, A, LDA, + $ DWORK( I13+1 ), N, C, LDC, DWORK( I12+1 ), NP+M, + $ DWORK( I14+1 ), N, RCOND( 3 ), DWORK( I15+1 ), N, + $ DWORK( I16+1 ), DWORK( I17+1 ), DWORK( I18+1 ), + $ DWORK( I19+1 ), N2+NP+M, DWORK( I20+1 ), N2+NP+M, + $ DWORK( I21+1 ), N2, -ONE, IWORK, DWORK( IWRK+1 ), + $ LDWORK-IWRK, BWORK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 3 + RETURN + END IF + LWA = INT( DWORK( IWRK+1 ) ) + IWRK + LWAMAX = MAX( LWA, LWAMAX ) +C + I22 = I16 + I23 = I22 + ( NP+M )*N + I24 = I23 + ( NP+M )*( NP+M ) + I25 = I24 + ( NP+M )*N + I26 = I25 + M*N +C + IWRK = I25 +C +C Compute Bx'*X . +C + CALL DGEMM( 'T', 'N', NP+M, N, N, ONE, DWORK( I13+1 ), N, + $ DWORK( I15+1 ), N, ZERO, DWORK( I22+1 ), NP+M ) +C +C Compute Rx + Bx'*X*Bx . +C + CALL DLACPY( 'F', NP+M, NP+M, DWORK( I12+1 ), NP+M, + $ DWORK( I23+1 ), NP+M ) + CALL DGEMM( 'N', 'N', NP+M, NP+M, N, ONE, DWORK( I22+1 ), NP+M, + $ DWORK( I13+1 ), N, ONE, DWORK( I23+1 ), NP+M ) +C +C Compute -( Sx' + Bx'*X*A ) . +C + DO 170 J = 1, N + DO 160 I = 1, NP+M + DWORK( I24+I+(J-1)*(NP+M) ) = DWORK( I14+J+(I-1)*N ) + 160 CONTINUE + 170 CONTINUE + CALL DGEMM( 'N', 'N', NP+M, N, N, -ONE, DWORK( I22+1 ), NP+M, + $ A, LDA, -ONE, DWORK( I24+1 ), NP+M ) +C +C Factorize Rx + Bx'*X*Bx . +C + RNORM = DLANSY( '1', 'U', NP+M, DWORK( I23+1 ), NP+M, + $ DWORK( IWRK+1 ) ) + CALL DSYTRF( 'U', NP+M, DWORK( I23+1 ), NP+M, IWORK, + $ DWORK( IWRK+1 ), LDWORK-IWRK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 5 + RETURN + END IF + LWA = INT( DWORK( IWRK+1 ) ) + IWRK + LWAMAX = MAX( LWA, LWAMAX ) + CALL DSYCON( 'U', NP+M, DWORK( I23+1 ), NP+M, IWORK, RNORM, + $ RCOND( 4 ), DWORK( IWRK+1 ), IWORK( NP+M+1), INFO2 ) +C -1 +C Compute F = -( Rx + Bx'*X*Bx ) ( Sx' + Bx'*X*A ) . +C + CALL DSYTRS( 'U', NP+M, N, DWORK( I23+1 ), NP+M, IWORK, + $ DWORK( I24+1 ), NP+M, INFO2 ) +C +C Compute B'*X . +C + CALL DGEMM( 'T', 'N', M, N, N, ONE, B, LDB, DWORK( I15+1 ), N, + $ ZERO, DWORK( I25+1 ), M ) +C +C Compute Im + B'*X*B . +C + CALL DLASET( 'F', M, M, ZERO, ONE, DWORK( I23+1 ), M ) + CALL DGEMM( 'N', 'N', M, M, N, ONE, DWORK( I25+1 ), M, B, LDB, + $ ONE, DWORK( I23+1 ), M ) +C +C Factorize Im + B'*X*B . +C + CALL DPOTRF( 'U', M, DWORK( I23+1 ), M, INFO2 ) +C -1 +C Compute ( Im + B'*X*B ) B'*X . +C + CALL DPOTRS( 'U', M, N, DWORK( I23+1 ), M, DWORK( I25+1 ), M, + $ INFO2 ) +C -1 +C Compute Dk = ( Im + B'*X*B ) B'*X*H . +C + CALL DGEMM( 'N', 'N', M, NP, N, ONE, DWORK( I25+1 ), M, + $ DWORK( I11+1 ), N, ZERO, DK, LDDK ) +C +C Compute Bk = -H + B*Dk . +C + CALL DLACPY( 'F', N, NP, DWORK( I11+1 ), N, BK, LDBK ) + CALL DGEMM( 'N', 'N', N, NP, M, ONE, B, LDB, DK, LDDK, -ONE, + $ BK, LDBK ) +C -1 +C Compute Dk*Z2 . +C + CALL DGEMM( 'N', 'N', M, NP, NP, ONE, DK, LDDK, DWORK( I8+1 ), + $ NP, ZERO, DWORK( I26+1 ), M ) +C +C Compute F1 + Z2*C . +C + CALL DLACPY( 'F', NP, N, DWORK( I24+1 ), NP+M, DWORK( I12+1 ), + $ NP ) + CALL DGEMM( 'N', 'N', NP, N, NP, ONE, DWORK( I7+1 ), NP, C, LDC, + $ ONE, DWORK( I12+1 ), NP ) +C -1 +C Compute Ck = F2 - Dk*Z2 *( F1 + Z2*C ) . +C + CALL DLACPY( 'F', M, N, DWORK( I24+NP+1 ), NP+M, CK, LDCK ) + CALL DGEMM( 'N', 'N', M, N, NP, -ONE, DWORK( I26+1 ), M, + $ DWORK( I12+1 ), NP, ONE, CK, LDCK ) +C +C Compute Ak = A + H*C + B*Ck . +C + CALL DLACPY( 'F', N, N, A, LDA, AK, LDAK ) + CALL DGEMM( 'N', 'N', N, N, NP, ONE, DWORK( I11+1 ), N, C, LDC, + $ ONE, AK, LDAK ) + CALL DGEMM( 'N', 'N', N, N, M, ONE, B, LDB, CK, LDCK, ONE, AK, + $ LDAK ) +C +C Workspace usage. +C + I1 = M*N + I2 = I1 + N2*N2 + I3 = I2 + N2 +C + IWRK = I3 + N2 +C +C Compute Dk*C . +C + CALL DGEMM( 'N', 'N', M, N, NP, ONE, DK, LDDK, C, LDC, ZERO, + $ DWORK, M ) +C +C Compute the closed-loop state matrix. +C + CALL DLACPY( 'F', N, N, A, LDA, DWORK( I1+1 ), N2 ) + CALL DGEMM( 'N', 'N', N, N, M, -ONE, B, LDB, DWORK, M, ONE, + $ DWORK( I1+1 ), N2 ) + CALL DGEMM( 'N', 'N', N, N, NP, -ONE, BK, LDBK, C, LDC, ZERO, + $ DWORK( I1+N+1 ), N2 ) + CALL DGEMM( 'N', 'N', N, N, M, ONE, B, LDB, CK, LDCK, ZERO, + $ DWORK( I1+N2*N+1 ), N2 ) + CALL DLACPY( 'F', N, N, AK, LDAK, DWORK( I1+N2*N+N+1 ), N2 ) +C +C Compute the closed-loop poles. +C + CALL DGEES( 'N', 'N', SELECT, N2, DWORK( I1+1 ), N2, SDIM, + $ DWORK( I2+1 ), DWORK( I3+1 ), DWORK( IWRK+1 ), N, + $ DWORK( IWRK+1 ), LDWORK-IWRK, BWORK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 4 + RETURN + END IF + LWA = INT( DWORK( IWRK+1 ) ) + IWRK + LWAMAX = MAX( LWA, LWAMAX ) +C +C Check the stability of the closed-loop system. +C + NS = 0 + DO 180 I = 1, N2 + IF( DLAPY2( DWORK( I2+I ), DWORK( I3+I ) ).GT.ONE ) NS = NS + 1 + 180 CONTINUE + IF( NS.GT.0 ) THEN + INFO = 6 + RETURN + END IF +C + DWORK( 1 ) = DBLE( LWAMAX ) + RETURN +C *** Last line of SB10KD *** + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB10KD.res Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,34 @@ + SB10KD EXAMPLE PROGRAM RESULTS + + + The controller state matrix AK is + + 0.0337 0.0222 0.0858 0.1264 -0.1872 0.1547 + 0.4457 0.0668 -0.2255 -0.3204 -0.4548 -0.0691 + -0.2419 -0.2506 -0.0982 -0.1321 -0.0130 -0.0838 + -0.4402 0.3654 -0.0335 -0.2444 0.6366 -0.6469 + -0.3623 0.3854 0.4162 0.4502 0.0065 0.1261 + -0.0121 -0.4377 0.0604 0.2265 -0.3389 0.4542 + + The controller input matrix BK is + + 0.0931 -0.0269 + -0.0872 0.1599 + 0.0956 -0.1469 + -0.1728 0.0129 + 0.2022 -0.1154 + 0.2419 -0.1737 + + The controller output matrix CK is + + -0.3677 0.2188 0.0403 -0.0854 0.3564 -0.3535 + 0.1624 -0.0708 0.0058 0.0606 -0.2163 0.1802 + + The controller matrix DK is + + -0.0857 -0.0246 + 0.0460 0.0074 + + The estimated condition numbers are + + 0.11269D-01 0.17596D-01 0.18225D+00 0.75968D-03
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB10ZD.dat Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,21 @@ + SB10LD EXAMPLE PROGRAM DATA + 6 2 3 + 0.2 0.0 3.0 0.0 -0.3 -0.1 + -3.0 0.2 -0.4 -0.3 0.0 0.0 + -0.1 0.1 -1.0 0.0 0.0 -3.0 + 1.0 0.0 0.0 -1.0 -1.0 0.0 + 0.0 0.3 0.6 2.0 0.1 -0.4 + 0.2 -4.0 0.0 0.0 0.2 -2.0 + -1.0 -2.0 + 1.0 3.0 + -3.0 -4.0 + 1.0 -2.0 + 0.0 1.0 + 1.0 5.0 + 1.0 -1.0 2.0 -2.0 0.0 -3.0 + -3.0 0.0 1.0 -1.0 1.0 -1.0 + 2.0 4.0 -3.0 0.0 5.0 1.0 + 10.0 -6.0 + -7.0 8.0 + 2.0 -4.0 + 1.1 0.0
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB10ZD.f Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,914 @@ + SUBROUTINE SB10ZD( N, M, NP, A, LDA, B, LDB, C, LDC, D, LDD, + $ FACTOR, AK, LDAK, BK, LDBK, CK, LDCK, DK, + $ LDDK, RCOND, TOL, IWORK, DWORK, LDWORK, BWORK, + $ INFO ) +C +C SLICOT RELEASE 5.0. +C +C Copyright (c) 2002-2010 NICONET e.V. +C +C This program is free software: you can redistribute it and/or +C modify it under the terms of the GNU General Public License as +C published by the Free Software Foundation, either version 2 of +C the License, or (at your option) any later version. +C +C This program is distributed in the hope that it will be useful, +C but WITHOUT ANY WARRANTY; without even the implied warranty of +C MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +C GNU General Public License for more details. +C +C You should have received a copy of the GNU General Public License +C along with this program. If not, see +C <http://www.gnu.org/licenses/>. +C +C PURPOSE +C +C To compute the matrices of the positive feedback controller +C +C | Ak | Bk | +C K = |----|----| +C | Ck | Dk | +C +C for the shaped plant +C +C | A | B | +C G = |---|---| +C | C | D | +C +C in the Discrete-Time Loop Shaping Design Procedure. +C +C ARGUMENTS +C +C Input/Output Parameters +C +C N (input) INTEGER +C The order of the plant. N >= 0. +C +C M (input) INTEGER +C The column size of the matrix B. M >= 0. +C +C NP (input) INTEGER +C The row size of the matrix C. NP >= 0. +C +C A (input) DOUBLE PRECISION array, dimension (LDA,N) +C The leading N-by-N part of this array must contain the +C system state matrix A of the shaped plant. +C +C LDA INTEGER +C The leading dimension of the array A. LDA >= max(1,N). +C +C B (input) DOUBLE PRECISION array, dimension (LDB,M) +C The leading N-by-M part of this array must contain the +C system input matrix B of the shaped plant. +C +C LDB INTEGER +C The leading dimension of the array B. LDB >= max(1,N). +C +C C (input) DOUBLE PRECISION array, dimension (LDC,N) +C The leading NP-by-N part of this array must contain the +C system output matrix C of the shaped plant. +C +C LDC INTEGER +C The leading dimension of the array C. LDC >= max(1,NP). +C +C D (input) DOUBLE PRECISION array, dimension (LDD,M) +C The leading NP-by-M part of this array must contain the +C system input/output matrix D of the shaped plant. +C +C LDD INTEGER +C The leading dimension of the array D. LDD >= max(1,NP). +C +C FACTOR (input) DOUBLE PRECISION +C = 1 implies that an optimal controller is required +C (not recommended); +C > 1 implies that a suboptimal controller is required +C achieving a performance FACTOR less than optimal. +C FACTOR >= 1. +C +C AK (output) DOUBLE PRECISION array, dimension (LDAK,N) +C The leading N-by-N part of this array contains the +C controller state matrix Ak. +C +C LDAK INTEGER +C The leading dimension of the array AK. LDAK >= max(1,N). +C +C BK (output) DOUBLE PRECISION array, dimension (LDBK,NP) +C The leading N-by-NP part of this array contains the +C controller input matrix Bk. +C +C LDBK INTEGER +C The leading dimension of the array BK. LDBK >= max(1,N). +C +C CK (output) DOUBLE PRECISION array, dimension (LDCK,N) +C The leading M-by-N part of this array contains the +C controller output matrix Ck. +C +C LDCK INTEGER +C The leading dimension of the array CK. LDCK >= max(1,M). +C +C DK (output) DOUBLE PRECISION array, dimension (LDDK,NP) +C The leading M-by-NP part of this array contains the +C controller matrix Dk. +C +C LDDK INTEGER +C The leading dimension of the array DK. LDDK >= max(1,M). +C +C RCOND (output) DOUBLE PRECISION array, dimension (6) +C RCOND(1) contains an estimate of the reciprocal condition +C number of the linear system of equations from +C which the solution of the P-Riccati equation is +C obtained; +C RCOND(2) contains an estimate of the reciprocal condition +C number of the linear system of equations from +C which the solution of the Q-Riccati equation is +C obtained; +C RCOND(3) contains an estimate of the reciprocal condition +C number of the matrix (gamma^2-1)*In - P*Q; +C RCOND(4) contains an estimate of the reciprocal condition +C number of the matrix Rx + Bx'*X*Bx; +C RCOND(5) contains an estimate of the reciprocal condition +C ^ +C number of the matrix Ip + D*Dk; +C RCOND(6) contains an estimate of the reciprocal condition +C ^ +C number of the matrix Im + Dk*D. +C +C Tolerances +C +C TOL DOUBLE PRECISION +C Tolerance used for checking the nonsingularity of the +C matrices to be inverted. If TOL <= 0, then a default value +C equal to sqrt(EPS) is used, where EPS is the relative +C machine precision. TOL < 1. +C +C Workspace +C +C IWORK INTEGER array, dimension 2*max(N,M+NP) +C +C DWORK DOUBLE PRECISION array, dimension (LDWORK) +C On exit, if INFO = 0, DWORK(1) contains the optimal value +C of LDWORK. +C +C LDWORK INTEGER +C The dimension of the array DWORK. +C LDWORK >= 16*N*N + 5*M*M + 7*NP*NP + 6*M*N + 7*M*NP + +C 7*N*NP + 6*N + 2*(M + NP) + +C max(14*N+23,16*N,2*M-1,2*NP-1). +C For good performance, LDWORK must generally be larger. +C +C BWORK LOGICAL array, dimension (2*N) +C +C Error Indicator +C +C INFO (output) INTEGER +C = 0: successful exit; +C < 0: if INFO = -i, the i-th argument had an illegal +C value; +C = 1: the P-Riccati equation is not solved successfully; +C = 2: the Q-Riccati equation is not solved successfully; +C = 3: the iteration to compute eigenvalues or singular +C values failed to converge; +C = 4: the matrix (gamma^2-1)*In - P*Q is singular; +C = 5: the matrix Rx + Bx'*X*Bx is singular; +C ^ +C = 6: the matrix Ip + D*Dk is singular; +C ^ +C = 7: the matrix Im + Dk*D is singular; +C = 8: the matrix Ip - D*Dk is singular; +C = 9: the matrix Im - Dk*D is singular; +C = 10: the closed-loop system is unstable. +C +C METHOD +C +C The routine implements the formulas given in [1]. +C +C REFERENCES +C +C [1] Gu, D.-W., Petkov, P.H., and Konstantinov, M.M. +C On discrete H-infinity loop shaping design procedure routines. +C Technical Report 00-6, Dept. of Engineering, Univ. of +C Leicester, UK, 2000. +C +C NUMERICAL ASPECTS +C +C The accuracy of the results depends on the conditioning of the +C two Riccati equations solved in the controller design. For +C better conditioning it is advised to take FACTOR > 1. +C +C CONTRIBUTORS +C +C P.Hr. Petkov, D.W. Gu and M.M. Konstantinov, May 2001. +C +C REVISIONS +C +C V. Sima, Research Institute for Informatics, Bucharest, July 2001. +C +C KEYWORDS +C +C H_infinity control, Loop-shaping design, Robust control. +C +C ****************************************************************** +C +C .. Parameters .. + DOUBLE PRECISION ZERO, ONE + PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 ) +C .. +C .. Scalar Arguments .. + INTEGER INFO, LDA, LDAK, LDB, LDBK, LDC, LDCK, LDD, + $ LDDK, LDWORK, M, N, NP + DOUBLE PRECISION FACTOR, TOL +C .. +C .. Array Arguments .. + INTEGER IWORK( * ) + LOGICAL BWORK( * ) + DOUBLE PRECISION A ( LDA, * ), AK( LDAK, * ), B ( LDB, * ), + $ BK( LDBK, * ), C ( LDC, * ), CK( LDCK, * ), + $ D ( LDD, * ), DK( LDDK, * ), DWORK( * ), + $ RCOND( 6 ) +C .. +C .. Local Scalars .. + INTEGER I, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, + $ I11, I12, I13, I14, I15, I16, I17, I18, I19, + $ I20, I21, I22, I23, I24, I25, I26, INFO2, IWRK, + $ J, LWAMAX, MINWRK, N2, NS, SDIM + DOUBLE PRECISION ANORM, GAMMA, TOLL +C .. +C .. External Functions .. + LOGICAL SELECT + DOUBLE PRECISION DLAMCH, DLANGE, DLANSY, DLAPY2 + EXTERNAL DLAMCH, DLANGE, DLANSY, DLAPY2, SELECT +C .. +C .. External Subroutines .. + EXTERNAL DCOPY, DGECON, DGEES, DGEMM, DGETRF, DGETRS, + $ DLACPY, DLASCL, DLASET, DPOTRF, DPOTRS, DSWAP, + $ DSYCON, DSYEV, DSYRK, DSYTRF, DSYTRS, DTRSM, + $ DTRTRS, MA02AD, MB01RX, MB02VD, SB02OD, XERBLA +C .. +C .. Intrinsic Functions .. + INTRINSIC INT, MAX, SQRT +C .. +C .. Executable Statements .. +C +C Decode and Test input parameters. +C + INFO = 0 + IF( N.LT.0 ) THEN + INFO = -1 + ELSE IF( M.LT.0 ) THEN + INFO = -2 + ELSE IF( NP.LT.0 ) THEN + INFO = -3 + ELSE IF( LDA.LT.MAX( 1, N ) ) THEN + INFO = -5 + ELSE IF( LDB.LT.MAX( 1, N ) ) THEN + INFO = -7 + ELSE IF( LDC.LT.MAX( 1, NP ) ) THEN + INFO = -9 + ELSE IF( LDD.LT.MAX( 1, NP ) ) THEN + INFO = -11 + ELSE IF( FACTOR.LT.ONE ) THEN + INFO = -12 + ELSE IF( LDAK.LT.MAX( 1, N ) ) THEN + INFO = -14 + ELSE IF( LDBK.LT.MAX( 1, N ) ) THEN + INFO = -16 + ELSE IF( LDCK.LT.MAX( 1, M ) ) THEN + INFO = -18 + ELSE IF( LDDK.LT.MAX( 1, M ) ) THEN + INFO = -20 + ELSE IF( TOL.GE.ONE ) THEN + INFO = -22 + END IF +C +C Compute workspace. +C + MINWRK = 16*N*N + 5*M*M + 7*NP*NP + 6*M*N + 7*M*NP + 7*N*NP + + $ 6*N + 2*(M + NP) + MAX( 14*N+23, 16*N, 2*M-1, 2*NP-1 ) + IF( LDWORK.LT.MINWRK ) THEN + INFO = -25 + END IF + IF( INFO.NE.0 ) THEN + CALL XERBLA( 'SB10ZD', -INFO ) + RETURN + END IF +C +C Quick return if possible. +C Note that some computation could be made if one or two of the +C dimension parameters N, M, and P are zero, but the results are +C not so meaningful. +C + IF( N.EQ.0 .OR. M.EQ.0 .OR. NP.EQ.0 ) THEN + RCOND( 1 ) = ONE + RCOND( 2 ) = ONE + RCOND( 3 ) = ONE + RCOND( 4 ) = ONE + RCOND( 5 ) = ONE + RCOND( 6 ) = ONE + DWORK( 1 ) = ONE + RETURN + END IF +C +C Set the default tolerance, if needed. +C + IF( TOL.LE.ZERO ) THEN + TOLL = SQRT( DLAMCH( 'Epsilon' ) ) + ELSE + TOLL = TOL + END IF +C +C Workspace usage. +C + N2 = 2*N + I1 = 1 + N*N + I2 = I1 + N*N + I3 = I2 + NP*NP + I4 = I3 + M*M + I5 = I4 + NP*NP + I6 = I5 + M*M + I7 = I6 + M*N + I8 = I7 + M*N + I9 = I8 + N*N + I10 = I9 + N*N + I11 = I10 + N2 + I12 = I11 + N2 + I13 = I12 + N2 + I14 = I13 + N2*N2 + I15 = I14 + N2*N2 +C + IWRK = I15 + N2*N2 + LWAMAX = 0 +C +C Compute R1 = Ip + D*D' . +C + CALL DLASET( 'U', NP, NP, ZERO, ONE, DWORK( I2 ), NP ) + CALL DSYRK( 'U', 'N', NP, M, ONE, D, LDD, ONE, DWORK( I2 ), NP ) + CALL DLACPY( 'U', NP, NP, DWORK( I2 ), NP, DWORK( I4 ), NP ) +C +C Factorize R1 = R'*R . +C + CALL DPOTRF( 'U', NP, DWORK( I4 ), NP, INFO2 ) +C -1 +C Compute C'*R in BK . +C + CALL MA02AD( 'F', NP, N, C, LDC, BK, LDBK ) + CALL DTRSM( 'R', 'U', 'N', 'N', N, NP, ONE, DWORK( I4 ), NP, BK, + $ LDBK ) +C +C Compute R2 = Im + D'*D . +C + CALL DLASET( 'U', M, M, ZERO, ONE, DWORK( I3 ), M ) + CALL DSYRK( 'U', 'T', M, NP, ONE, D, LDD, ONE, DWORK( I3 ), M ) + CALL DLACPY( 'U', M, M, DWORK( I3 ), M, DWORK( I5 ), M ) +C +C Factorize R2 = U'*U . +C + CALL DPOTRF( 'U', M, DWORK( I5 ), M, INFO2 ) +C -1 +C Compute (U )'*B' . +C + CALL MA02AD( 'F', N, M, B, LDB, DWORK( I6 ), M ) + CALL DTRTRS( 'U', 'T', 'N', M, N, DWORK( I5 ), M, DWORK( I6 ), M, + $ INFO2 ) +C +C Compute D'*C . +C + CALL DGEMM( 'T', 'N', M, N, NP, ONE, D, LDD, C, LDC, ZERO, + $ DWORK( I7 ), M ) +C -1 +C Compute (U )'*D'*C . +C + CALL DTRTRS( 'U', 'T', 'N', M, N, DWORK( I5 ), M, DWORK( I7 ), M, + $ INFO2 ) +C -1 +C Compute Ar = A - B*R2 D'*C . +C + CALL DLACPY( 'F', N, N, A, LDA, DWORK( I8 ), N ) + CALL DGEMM( 'T', 'N', N, N, M, -ONE, DWORK( I6 ), M, DWORK( I7 ), + $ M, ONE, DWORK( I8 ), N ) +C -1 +C Compute Cr = C'*R1 *C . +C + CALL DSYRK( 'U', 'N', N, NP, ONE, BK, LDBK, ZERO, DWORK( I9 ), N ) +C -1 +C Compute Dr = B*R2 B' in AK . +C + CALL DSYRK( 'U', 'T', N, M, ONE, DWORK( I6 ), M, ZERO, AK, LDAK ) +C -1 +C Solution of the Riccati equation Ar'*P*(In + Dr*P) Ar - P + +C Cr = 0 . + CALL SB02OD( 'D', 'G', 'N', 'U', 'Z', 'S', N, M, NP, DWORK( I8 ), + $ N, AK, LDAK, DWORK( I9 ), N, DWORK, M, DWORK, N, + $ RCOND( 1 ), DWORK, N, DWORK( I10 ), DWORK( I11 ), + $ DWORK( I12 ), DWORK( I13 ), N2, DWORK( I14 ), N2, + $ DWORK( I15 ), N2, -ONE, IWORK, DWORK( IWRK ), + $ LDWORK-IWRK+1, BWORK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 1 + RETURN + END IF + LWAMAX = MAX( LWAMAX, INT( DWORK( IWRK ) ) + IWRK - 1 ) +C +C Transpose Ar . +C + DO 10 J = 1, N - 1 + CALL DSWAP( J, DWORK( I8+J ), N, DWORK( I8+J*N ), 1 ) + 10 CONTINUE +C -1 +C Solution of the Riccati equation Ar*Q*(In + Cr*Q) *Ar' - Q + +C Dr = 0 . + CALL SB02OD( 'D', 'G', 'N', 'U', 'Z', 'S', N, M, NP, DWORK( I8 ), + $ N, DWORK( I9 ), N, AK, LDAK, DWORK, M, DWORK, N, + $ RCOND( 2 ), DWORK( I1 ), N, DWORK( I10 ), + $ DWORK( I11 ), DWORK( I12 ), DWORK( I13 ), N2, + $ DWORK( I14 ), N2, DWORK( I15 ), N2, -ONE, IWORK, + $ DWORK( IWRK ), LDWORK-IWRK+1, BWORK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 2 + RETURN + END IF + LWAMAX = MAX( LWAMAX, INT( DWORK( IWRK ) ) + IWRK - 1 ) +C +C Compute gamma. +C + CALL DGEMM( 'N', 'N', N, N, N, ONE, DWORK( I1 ), N, DWORK, N, + $ ZERO, DWORK( I8 ), N ) + CALL DGEES( 'N', 'N', SELECT, N, DWORK( I8 ), N, SDIM, + $ DWORK( I10 ), DWORK( I11 ), DWORK( IWRK ), N, + $ DWORK( IWRK ), LDWORK-IWRK+1, BWORK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 3 + RETURN + END IF + LWAMAX = MAX( LWAMAX, INT( DWORK( IWRK ) ) + IWRK - 1 ) + GAMMA = ZERO +C + DO 20 I = 0, N - 1 + GAMMA = MAX( GAMMA, DWORK( I10+I ) ) + 20 CONTINUE +C + GAMMA = FACTOR*SQRT( ONE + GAMMA ) +C +C Workspace usage. +C + I5 = I4 + NP*NP + I6 = I5 + M*M + I7 = I6 + NP*NP + I8 = I7 + NP*NP + I9 = I8 + NP*NP + I10 = I9 + NP + I11 = I10 + NP*NP + I12 = I11 + M*M + I13 = I12 + M +C + IWRK = I13 + M*M +C +C Compute the eigenvalues and eigenvectors of R1 . +C + CALL DLACPY( 'U', NP, NP, DWORK( I2 ), NP, DWORK( I8 ), NP ) + CALL DSYEV( 'V', 'U', NP, DWORK( I8 ), NP, DWORK( I9 ), + $ DWORK( IWRK ), LDWORK-IWRK+1, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 3 + RETURN + END IF + LWAMAX = MAX( LWAMAX, INT( DWORK( IWRK ) ) + IWRK - 1 ) +C -1/2 +C Compute R1 . +C + DO 40 J = 1, NP + DO 30 I = 1, NP + DWORK( I10-1+I+(J-1)*NP ) = DWORK( I8-1+J+(I-1)*NP ) / + $ SQRT( DWORK( I9+I-1 ) ) + 30 CONTINUE + 40 CONTINUE +C + CALL DGEMM( 'N', 'N', NP, NP, NP, ONE, DWORK( I8 ), NP, + $ DWORK( I10 ), NP, ZERO, DWORK( I4 ), NP ) +C +C Compute the eigenvalues and eigenvectors of R2 . +C + CALL DLACPY( 'U', M, M, DWORK( I3 ), M, DWORK( I11 ), M ) + CALL DSYEV( 'V', 'U', M, DWORK( I11 ), M, DWORK( I12 ), + $ DWORK( IWRK ), LDWORK-IWRK+1, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 3 + RETURN + END IF + LWAMAX = MAX( LWAMAX, INT( DWORK( IWRK ) ) + IWRK - 1 ) +C -1/2 +C Compute R2 . +C + DO 60 J = 1, M + DO 50 I = 1, M + DWORK( I13-1+I+(J-1)*M ) = DWORK( I11-1+J+(I-1)*M ) / + $ SQRT( DWORK( I12+I-1 ) ) + 50 CONTINUE + 60 CONTINUE +C + CALL DGEMM( 'N', 'N', M, M, M, ONE, DWORK( I11 ), M, DWORK( I13 ), + $ M, ZERO, DWORK( I5 ), M ) +C +C Compute R1 + C*Q*C' . +C + CALL DGEMM( 'N', 'T', N, NP, N, ONE, DWORK( I1 ), N, C, LDC, + $ ZERO, BK, LDBK ) + CALL MB01RX( 'L', 'U', 'N', NP, N, ONE, ONE, DWORK( I2 ), NP, + $ C, LDC, BK, LDBK, INFO2 ) + CALL DLACPY( 'U', NP, NP, DWORK( I2 ), NP, DWORK( I8 ), NP ) +C +C Compute the eigenvalues and eigenvectors of R1 + C*Q*C' . +C + CALL DSYEV( 'V', 'U', NP, DWORK( I8 ), NP, DWORK( I9 ), + $ DWORK( IWRK ), LDWORK-IWRK+1, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 3 + RETURN + END IF + LWAMAX = MAX( LWAMAX, INT( DWORK( IWRK ) ) + IWRK - 1 ) +C -1 +C Compute ( R1 + C*Q*C' ) . +C + DO 80 J = 1, NP + DO 70 I = 1, NP + DWORK( I10-1+I+(J-1)*NP ) = DWORK( I8-1+J+(I-1)*NP ) / + $ DWORK( I9+I-1 ) + 70 CONTINUE + 80 CONTINUE +C + CALL DGEMM( 'N', 'N', NP, NP, NP, ONE, DWORK( I8 ), NP, + $ DWORK( I10 ), NP, ZERO, DWORK( I6 ), NP ) +C -1 +C Compute Z2 . +C + DO 100 J = 1, NP + DO 90 I = 1, NP + DWORK( I10-1+I+(J-1)*NP ) = DWORK( I8-1+J+(I-1)*NP )* + $ SQRT( DWORK( I9+I-1 ) ) + 90 CONTINUE + 100 CONTINUE +C + CALL DGEMM( 'N', 'N', NP, NP, NP, ONE, DWORK( I8 ), NP, + $ DWORK( I10 ), NP, ZERO, DWORK( I7 ), NP ) +C +C Workspace usage. +C + I9 = I8 + N*NP + I10 = I9 + N*NP + I11 = I10 + NP*M + I12 = I11 + ( NP + M )*( NP + M ) + I13 = I12 + N*( NP + M ) + I14 = I13 + N*( NP + M ) + I15 = I14 + N*N + I16 = I15 + N*N + I17 = I16 + ( NP + M )*N + I18 = I17 + ( NP + M )*( NP + M ) + I19 = I18 + ( NP + M )*N + I20 = I19 + M*N + I21 = I20 + M*NP + I22 = I21 + NP*N + I23 = I22 + N*N + I24 = I23 + N*NP + I25 = I24 + NP*NP + I26 = I25 + M*M +C + IWRK = I26 + N*M +C +C Compute A*Q*C' + B*D' . +C + CALL DGEMM( 'N', 'T', N, NP, M, ONE, B, LDB, D, LDD, ZERO, + $ DWORK( I8 ), N ) + CALL DGEMM( 'N', 'N', N, NP, N, ONE, A, LDA, BK, LDBK, + $ ONE, DWORK( I8 ), N ) +C -1 +C Compute H = -( A*Q*C'+B*D' )*( R1 + C*Q*C' ) . +C + CALL DGEMM( 'N', 'N', N, NP, NP, -ONE, DWORK( I8 ), N, + $ DWORK( I6 ), NP, ZERO, DWORK( I9 ), N ) +C -1/2 +C Compute R1 D . +C + CALL DGEMM( 'N', 'N', NP, M, NP, ONE, DWORK( I4 ), NP, D, LDD, + $ ZERO, DWORK( I10 ), NP ) +C +C Compute Rx . +C + DO 110 J = 1, NP + CALL DCOPY( J, DWORK( I2+(J-1)*NP ), 1, + $ DWORK( I11+(J-1)*(NP+M) ), 1 ) + DWORK( I11-1+J+(J-1)*(NP+M) ) = DWORK( I2-1+J+(J-1)*NP ) - + $ GAMMA*GAMMA + 110 CONTINUE +C + CALL DGEMM( 'N', 'N', NP, M, NP, ONE, DWORK( I7 ), NP, + $ DWORK( I10 ), NP, ZERO, DWORK( I11+(NP+M)*NP ), + $ NP+M ) + CALL DLASET( 'U', M, M, ZERO, ONE, DWORK( I11+(NP+M)*NP+NP ), + $ NP+M ) +C +C Compute Bx . +C + CALL DGEMM( 'N', 'N', N, NP, NP, -ONE, DWORK( I9 ), N, + $ DWORK( I7 ), NP, ZERO, DWORK( I12 ), N ) + CALL DGEMM( 'N', 'N', N, M, M, ONE, B, LDB, DWORK( I5 ), M, + $ ZERO, DWORK( I12+N*NP ), N ) +C +C Compute Sx . +C + CALL DGEMM( 'T', 'N', N, NP, NP, ONE, C, LDC, DWORK( I7 ), NP, + $ ZERO, DWORK( I13 ), N ) + CALL DGEMM( 'T', 'N', N, M, NP, ONE, C, LDC, DWORK( I10 ), NP, + $ ZERO, DWORK( I13+N*NP ), N ) +C +C Compute (gamma^2 - 1)*In - P*Q . +C + CALL DLASET( 'F', N, N, ZERO, GAMMA*GAMMA-ONE, DWORK( I14 ), N ) + CALL DGEMM( 'N', 'N', N, N, N, -ONE, DWORK, N, DWORK( I1 ), N, + $ ONE, DWORK( I14 ), N ) +C -1 +C Compute X = ((gamma^2 - 1)*In - P*Q) *gamma^2*P . +C + CALL DLACPY( 'F', N, N, DWORK, N, DWORK( I15 ), N ) + CALL DLASCL( 'G', 0, 0, ONE, GAMMA*GAMMA, N, N, DWORK( I15 ), N, + $ INFO ) + ANORM = DLANGE( '1', N, N, DWORK( I14 ), N, DWORK( IWRK ) ) + CALL DGETRF( N, N, DWORK( I14 ), N, IWORK, INFO2 ) + IF( INFO2.GT.0 ) THEN + INFO = 4 + RETURN + END IF + CALL DGECON( '1', N, DWORK( I14 ), N, ANORM, RCOND( 3 ), + $ DWORK( IWRK ), IWORK( N+1 ), INFO2 ) +C +C Return if the matrix is singular to working precision. +C + IF( RCOND( 3 ).LT.TOLL ) THEN + INFO = 4 + RETURN + END IF + CALL DGETRS( 'N', N, N, DWORK( I14 ), N, IWORK, DWORK( I15 ), + $ N, INFO2 ) +C +C Compute Bx'*X . +C + CALL DGEMM( 'T', 'N', NP+M, N, N, ONE, DWORK( I12 ), N, + $ DWORK( I15 ), N, ZERO, DWORK( I16 ), NP+M ) +C +C Compute Rx + Bx'*X*Bx . +C + CALL DLACPY( 'U', NP+M, NP+M, DWORK( I11 ), NP+M, DWORK( I17 ), + $ NP+M ) + CALL MB01RX( 'L', 'U', 'N', NP+M, N, ONE, ONE, DWORK( I17 ), NP+M, + $ DWORK( I16 ), NP+M, DWORK( I12 ), N, INFO2 ) +C +C Compute -( Sx' + Bx'*X*A ) . +C + CALL MA02AD( 'F', N, NP+M, DWORK( I13 ), N, DWORK( I18 ), NP+M ) + CALL DGEMM( 'N', 'N', NP+M, N, N, -ONE, DWORK( I16 ), NP+M, + $ A, LDA, -ONE, DWORK( I18 ), NP+M ) +C +C Factorize Rx + Bx'*X*Bx . +C + ANORM = DLANSY( '1', 'U', NP+M, DWORK( I17 ), NP+M, + $ DWORK( IWRK ) ) + CALL DSYTRF( 'U', NP+M, DWORK( I17 ), NP+M, IWORK, + $ DWORK( IWRK ), LDWORK-IWRK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 5 + RETURN + END IF + CALL DSYCON( 'U', NP+M, DWORK( I17 ), NP+M, IWORK, ANORM, + $ RCOND( 4 ), DWORK( IWRK ), IWORK( NP+M+1), INFO2 ) +C +C Return if the matrix is singular to working precision. +C + IF( RCOND( 4 ).LT.TOLL ) THEN + INFO = 5 + RETURN + END IF +C -1 +C Compute F = -( Rx + Bx'*X*Bx ) ( Sx' + Bx'*X*A ) . +C + CALL DSYTRS( 'U', NP+M, N, DWORK( I17 ), NP+M, IWORK, + $ DWORK( I18 ), NP+M, INFO2 ) +C +C Compute B'*X . +C + CALL DGEMM( 'T', 'N', M, N, N, ONE, B, LDB, DWORK( I15 ), N, + $ ZERO, DWORK( I19 ), M ) +C +C Compute -( D' - B'*X*H ) . +C + DO 130 J = 1, NP + DO 120 I = 1, M + DWORK( I20-1+I+(J-1)*M ) = -D( J, I ) + 120 CONTINUE + 130 CONTINUE +C + CALL DGEMM( 'N', 'N', M, NP, N, ONE, DWORK( I19 ), M, + $ DWORK( I9 ), N, ONE, DWORK( I20 ), M ) +C -1 +C Compute C + Z2 *F1 . +C + CALL DLACPY( 'F', NP, N, C, LDC, DWORK( I21 ), NP ) + CALL DGEMM( 'N', 'N', NP, N, NP, ONE, DWORK( I7 ), NP, + $ DWORK( I18 ), NP+M, ONE, DWORK( I21 ), NP ) +C +C Compute R2 + B'*X*B . +C + CALL MB01RX( 'L', 'U', 'N', M, N, ONE, ONE, DWORK( I3 ), M, + $ DWORK( I19 ), M, B, LDB, INFO2 ) +C +C Factorize R2 + B'*X*B . +C + CALL DPOTRF( 'U', M, DWORK( I3 ), M, INFO2 ) +C ^ -1 +C Compute Dk = -( R2 + B'*X*B ) (D' - B'*X*H) . +C + CALL DLACPY( 'F', M, NP, DWORK( I20 ), M, DK, LDDK ) + CALL DPOTRS( 'U', M, NP, DWORK( I3 ), M, DK, LDDK, INFO2 ) +C ^ ^ +C Compute Bk = -H + B*Dk . +C + CALL DLACPY( 'F', N, NP, DWORK( I9 ), N, DWORK( I23 ), N ) + CALL DGEMM( 'N', 'N', N, NP, M, ONE, B, LDB, DK, LDDK, + $ -ONE, DWORK( I23 ), N ) +C -1/2 +C Compute R2 *F2 . +C + CALL DGEMM( 'N', 'N', M, N, M, ONE, DWORK( I5 ), M, + $ DWORK( I18+NP ), NP+M, ZERO, CK, LDCK ) +C ^ -1/2 ^ -1 +C Compute Ck = R2 *F2 - Dk*( C + Z2 *F1 ) . +C + CALL DGEMM( 'N', 'N', M, N, NP, -ONE, DK, LDDK, + $ DWORK( I21 ), NP, ONE, CK, LDCK ) +C ^ ^ +C Compute Ak = A + H*C + B*Ck . +C + CALL DLACPY( 'F', N, N, A, LDA, AK, LDAK ) + CALL DGEMM( 'N', 'N', N, N, NP, ONE, DWORK( I9 ), N, C, LDC, + $ ONE, AK, LDAK ) + CALL DGEMM( 'N', 'N', N, N, M, ONE, B, LDB, CK, LDCK, + $ ONE, AK, LDAK ) +C ^ +C Compute Ip + D*Dk . +C + CALL DLASET( 'Full', NP, NP, ZERO, ONE, DWORK( I24 ), NP ) + CALL DGEMM( 'N', 'N', NP, NP, M, ONE, D, LDD, DK, LDDK, + $ ONE, DWORK( I24 ), NP ) +C ^ +C Compute Im + Dk*D . +C + CALL DLASET( 'Full', M, M, ZERO, ONE, DWORK( I25 ), M ) + CALL DGEMM( 'N', 'N', M, M, NP, ONE, DK, LDDK, D, LDD, + $ ONE, DWORK( I25 ), M ) +C ^ ^ ^ ^ -1 +C Compute Ck = M*Ck, M = (Im + Dk*D) . +C + ANORM = DLANGE( '1', M, M, DWORK( I25 ), M, DWORK( IWRK ) ) + CALL DGETRF( M, M, DWORK( I25 ), M, IWORK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 7 + RETURN + END IF + CALL DGECON( '1', M, DWORK( I25 ), M, ANORM, RCOND( 6 ), + $ DWORK( IWRK ), IWORK( M+1 ), INFO2 ) +C +C Return if the matrix is singular to working precision. +C + IF( RCOND( 6 ).LT.TOLL ) THEN + INFO = 7 + RETURN + END IF + CALL DGETRS( 'N', M, N, DWORK( I25 ), M, IWORK, CK, LDCK, INFO2 ) +C ^ ^ +C Compute Dk = M*Dk . +C + CALL DGETRS( 'N', M, NP, DWORK( I25 ), M, IWORK, DK, LDDK, INFO2 ) +C ^ +C Compute Bk*D . +C + CALL DGEMM( 'N', 'N', N, M, NP, ONE, DWORK( I23 ), N, D, LDD, + $ ZERO, DWORK( I26 ), N ) +C ^ ^ +C Compute Ak = Ak - Bk*D*Ck. +C + CALL DGEMM( 'N', 'N', N, N, M, -ONE, DWORK( I26 ), N, CK, LDCK, + $ ONE, AK, LDAK ) +C ^ ^ -1 +C Compute Bk = Bk*(Ip + D*Dk) . +C + ANORM = DLANGE( '1', NP, NP, DWORK( I24 ), NP, DWORK( IWRK ) ) + CALL DLACPY( 'Full', N, NP, DWORK( I23 ), N, BK, LDBK ) + CALL MB02VD( 'N', N, NP, DWORK( I24 ), NP, IWORK, BK, LDBK, + $ INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 6 + RETURN + END IF + CALL DGECON( '1', NP, DWORK( I24 ), NP, ANORM, RCOND( 5 ), + $ DWORK( IWRK ), IWORK( NP+1 ), INFO2 ) +C +C Return if the matrix is singular to working precision. +C + IF( RCOND( 5 ).LT.TOLL ) THEN + INFO = 6 + RETURN + END IF +C +C Workspace usage. +C + I2 = 1 + NP*NP + I3 = I2 + N*NP + I4 = I3 + M*M + I5 = I4 + N*M + I6 = I5 + NP*N + I7 = I6 + M*N + I8 = I7 + N2*N2 + I9 = I8 + N2 +C + IWRK = I9 + N2 +C +C Compute Ip - D*Dk . +C + CALL DLASET( 'Full', NP, NP, ZERO, ONE, DWORK, NP ) + CALL DGEMM( 'N', 'N', NP, NP, M, -ONE, D, LDD, DK, LDDK, ONE, + $ DWORK, NP ) +C -1 +C Compute Bk*(Ip-D*Dk) . +C + CALL DLACPY( 'Full', N, NP, BK, LDBK, DWORK( I2 ), N ) + CALL MB02VD( 'N', N, NP, DWORK, NP, IWORK, DWORK( I2 ), N, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 8 + RETURN + END IF +C +C Compute Im - Dk*D . +C + CALL DLASET( 'Full', M, M, ZERO, ONE, DWORK( I3 ), M ) + CALL DGEMM( 'N', 'N', M, M, NP, -ONE, DK, LDDK, D, LDD, ONE, + $ DWORK( I3 ), M ) +C -1 +C Compute B*(Im-Dk*D) . +C + CALL DLACPY( 'Full', N, M, B, LDB, DWORK( I4 ), N ) + CALL MB02VD( 'N', N, M, DWORK( I3 ), M, IWORK, DWORK( I4 ), N, + $ INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 9 + RETURN + END IF +C +C Compute D*Ck . +C + CALL DGEMM( 'N', 'N', NP, N, M, ONE, D, LDD, CK, LDCK, ZERO, + $ DWORK( I5 ), NP ) +C +C Compute Dk*C . +C + CALL DGEMM( 'N', 'N', M, N, NP, ONE, DK, LDDK, C, LDC, ZERO, + $ DWORK( I6 ), M ) +C +C Compute the closed-loop state matrix. +C + CALL DLACPY( 'F', N, N, A, LDA, DWORK( I7 ), N2 ) + CALL DGEMM( 'N', 'N', N, N, M, ONE, DWORK( I4 ), N, + $ DWORK( I6 ), M, ONE, DWORK( I7 ), N2 ) + CALL DGEMM( 'N', 'N', N, N, M, ONE, DWORK( I4 ), N, CK, LDCK, + $ ZERO, DWORK( I7+N2*N ), N2 ) + CALL DGEMM( 'N', 'N', N, N, NP, ONE, DWORK( I2 ), N, C, LDC, + $ ZERO, DWORK( I7+N ), N2 ) + CALL DLACPY( 'F', N, N, AK, LDAK, DWORK( I7+N2*N+N ), N2 ) + CALL DGEMM( 'N', 'N', N, N, NP, ONE, DWORK( I2 ), N, + $ DWORK( I5 ), NP, ONE, DWORK( I7+N2*N+N ), N2 ) +C +C Compute the closed-loop poles. +C + CALL DGEES( 'N', 'N', SELECT, N2, DWORK( I7 ), N2, SDIM, + $ DWORK( I8 ), DWORK( I9 ), DWORK( IWRK ), N, + $ DWORK( IWRK ), LDWORK-IWRK+1, BWORK, INFO2 ) + IF( INFO2.NE.0 ) THEN + INFO = 3 + RETURN + END IF + LWAMAX = MAX( LWAMAX, INT( DWORK( IWRK ) ) + IWRK - 1 ) +C +C Check the stability of the closed-loop system. +C + NS = 0 +C + DO 140 I = 0, N2 - 1 + IF( DLAPY2( DWORK( I8+I ), DWORK( I9+I ) ).GT.ONE ) + $ NS = NS + 1 + 140 CONTINUE +C + IF( NS.GT.0 ) THEN + INFO = 10 + RETURN + END IF +C + DWORK( 1 ) = DBLE( LWAMAX ) + RETURN +C *** Last line of SB10ZD *** + END
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/SB10ZD.res Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,35 @@ + SB10ZD EXAMPLE PROGRAM RESULTS + + + The controller state matrix AK is + + 1.0128 0.5101 -0.1546 1.1300 3.3759 0.4911 + -2.1257 -1.4517 -0.4486 0.3493 -1.5506 -1.4296 + -1.0930 -0.6026 -0.1344 0.2253 -1.5625 -0.6762 + 0.3207 0.1698 0.2376 -1.1781 -0.8705 0.2896 + 0.5017 0.9006 0.0668 2.3613 0.2049 0.3703 + 1.0787 0.6703 0.2783 -0.7213 0.4918 0.7435 + + The controller input matrix BK is + + 0.4132 0.3112 -0.8077 + 0.2140 0.4253 0.1811 + -0.0710 0.0807 0.3558 + -0.0121 -0.2019 0.0249 + 0.1047 0.1399 -0.0457 + -0.2542 -0.3472 0.0523 + + The controller output matrix CK is + + -0.0372 -0.0456 -0.0040 0.0962 -0.2059 -0.0571 + 0.1999 0.2994 0.1335 -0.0251 -0.3108 0.2048 + + The controller matrix DK is + + 0.0629 -0.0022 0.0363 + -0.0228 0.0195 0.0600 + + The estimated condition numbers are + + 0.27949D-03 0.66679D-03 0.45677D-01 0.23433D-07 0.68495D-01 + 0.76854D-01
--- a/main/control/devel/ncfsyn/makefile_ncfsyn.m Sun Jul 31 19:51:16 2011 +0000 +++ b/main/control/devel/ncfsyn/makefile_ncfsyn.m Sun Jul 31 21:57:09 2011 +0000 @@ -6,3 +6,13 @@ MA02AD.f MB02PD.f MB01SD.f MB01UD.f SB03SY.f \ MB01RX.f SB03MX.f SB03SX.f MB01RY.f SB03QY.f \ SB03QX.f SB03MY.f SB04PX.f SB03MV.f SB03MW.f + +mkoctfile "-Wl,-framework" "-Wl,vecLib" \ + slsb10kd.cc \ + SB10KD.f SB02OD.f select.f SB02OY.f SB02OW.f \ + SB02OV.f SB02MV.f SB02OU.f SB02MR.f + +mkoctfile "-Wl,-framework" "-Wl,vecLib" \ + SB10ZD.f MA02AD.f SB02OD.f select.f MB01RX.f \ + MB02VD.f SB02OY.f SB02OW.f SB02OV.f SB02OU.f \ + SB02MR.f MA02GD.f SB02MV.f \ No newline at end of file
--- a/main/control/devel/ncfsyn/ncfsyn.m Sun Jul 31 19:51:16 2011 +0000 +++ b/main/control/devel/ncfsyn/ncfsyn.m Sun Jul 31 21:57:09 2011 +0000 @@ -54,7 +54,7 @@ elseif (any (d(:))) # discrete-time, d != 0 [ak, bk, ck, dk, rcond] = slsb10zd (a, b, c, d, factor); else # discrete-time, d == 0 - [ak, bk, ck, dk, rcond] = slsb10kd (a, b, c, d, factor); + [ak, bk, ck, dk, rcond] = slsb10kd (a, b, c, factor); endif ## controller @@ -194,3 +194,108 @@ %!assert (BK, BKe, 1e-4); %!assert (CK, CKe, 1e-4); %!assert (DK, DKe, 1e-4); + + +## discrete-time case D==0, direct access to sb10kd +%!shared AK, BK, CK, DK, RCOND, AKe, BKe, CKe, DKe, RCONDe +%! A = [ 0.2 0.0 0.3 0.0 -0.3 -0.1 +%! -0.3 0.2 -0.4 -0.3 0.0 0.0 +%! -0.1 0.1 -0.1 0.0 0.0 -0.3 +%! 0.1 0.0 0.0 -0.1 -0.1 0.0 +%! 0.0 0.3 0.6 0.2 0.1 -0.4 +%! 0.2 -0.4 0.0 0.0 0.2 -0.2 ]; +%! +%! B = [ -1.0 -2.0 +%! 1.0 3.0 +%! -3.0 -4.0 +%! 1.0 -2.0 +%! 0.0 1.0 +%! 1.0 5.0 ]; +%! +%! C = [ 1.0 -1.0 2.0 -2.0 0.0 -3.0 +%! -3.0 0.0 1.0 -1.0 1.0 -1.0 ]; +%! +%! FACTOR = 1.1; +%! +%! [AK, BK, CK, DK, RCOND] = slsb10kd (A, B, C, FACTOR); +%! +%! AKe = [ 0.0337 0.0222 0.0858 0.1264 -0.1872 0.1547 +%! 0.4457 0.0668 -0.2255 -0.3204 -0.4548 -0.0691 +%! -0.2419 -0.2506 -0.0982 -0.1321 -0.0130 -0.0838 +%! -0.4402 0.3654 -0.0335 -0.2444 0.6366 -0.6469 +%! -0.3623 0.3854 0.4162 0.4502 0.0065 0.1261 +%! -0.0121 -0.4377 0.0604 0.2265 -0.3389 0.4542 ]; +%! +%! BKe = [ 0.0931 -0.0269 +%! -0.0872 0.1599 +%! 0.0956 -0.1469 +%! -0.1728 0.0129 +%! 0.2022 -0.1154 +%! 0.2419 -0.1737 ]; +%! +%! CKe = [ -0.3677 0.2188 0.0403 -0.0854 0.3564 -0.3535 +%! 0.1624 -0.0708 0.0058 0.0606 -0.2163 0.1802 ]; +%! +%! DKe = [ -0.0857 -0.0246 +%! 0.0460 0.0074 ]; +%! +%! RCONDe = [ 0.11269D-01 0.17596D-01 0.18225D+00 0.75968D-03 ].'; +%! +%!assert (AK, AKe, 1e-4); +%!assert (BK, BKe, 1e-4); +%!assert (CK, CKe, 1e-4); +%!assert (DK, DKe, 1e-4); +%!assert (RCOND, RCONDe, 1e-4); + + +## discrete-time case D==0 +%!shared AK, BK, CK, DK, RCOND, AKe, BKe, CKe, DKe, RCONDe +%! A = [ 0.2 0.0 0.3 0.0 -0.3 -0.1 +%! -0.3 0.2 -0.4 -0.3 0.0 0.0 +%! -0.1 0.1 -0.1 0.0 0.0 -0.3 +%! 0.1 0.0 0.0 -0.1 -0.1 0.0 +%! 0.0 0.3 0.6 0.2 0.1 -0.4 +%! 0.2 -0.4 0.0 0.0 0.2 -0.2 ]; +%! +%! B = [ -1.0 -2.0 +%! 1.0 3.0 +%! -3.0 -4.0 +%! 1.0 -2.0 +%! 0.0 1.0 +%! 1.0 5.0 ]; +%! +%! C = [ 1.0 -1.0 2.0 -2.0 0.0 -3.0 +%! -3.0 0.0 1.0 -1.0 1.0 -1.0 ]; +%! +%! FACTOR = 1.1; +%! +%! G = ss (A, B, C, [], 1); +%! K = ncfsyn (G, [], [], FACTOR); +%! [AK, BK, CK, DK] = ssdata (K); +%! +%! AKe = [ 0.0337 0.0222 0.0858 0.1264 -0.1872 0.1547 +%! 0.4457 0.0668 -0.2255 -0.3204 -0.4548 -0.0691 +%! -0.2419 -0.2506 -0.0982 -0.1321 -0.0130 -0.0838 +%! -0.4402 0.3654 -0.0335 -0.2444 0.6366 -0.6469 +%! -0.3623 0.3854 0.4162 0.4502 0.0065 0.1261 +%! -0.0121 -0.4377 0.0604 0.2265 -0.3389 0.4542 ]; +%! +%! BKe = [ 0.0931 -0.0269 +%! -0.0872 0.1599 +%! 0.0956 -0.1469 +%! -0.1728 0.0129 +%! 0.2022 -0.1154 +%! 0.2419 -0.1737 ]; +%! +%! CKe = [ -0.3677 0.2188 0.0403 -0.0854 0.3564 -0.3535 +%! 0.1624 -0.0708 0.0058 0.0606 -0.2163 0.1802 ]; +%! +%! DKe = [ -0.0857 -0.0246 +%! 0.0460 0.0074 ]; +%! +%! RCONDe = [ 0.11269D-01 0.17596D-01 0.18225D+00 0.75968D-03 ].'; +%! +%!assert (AK, AKe, 1e-4); +%!assert (BK, BKe, 1e-4); +%!assert (CK, CKe, 1e-4); +%!assert (DK, DKe, 1e-4);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main/control/devel/ncfsyn/slsb10kd.cc Sun Jul 31 21:57:09 2011 +0000 @@ -0,0 +1,148 @@ +/* + +Copyright (C) 2011 Lukas F. Reichlin + +This file is part of LTI Syncope. + +LTI Syncope is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +LTI Syncope is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with LTI Syncope. If not, see <http://www.gnu.org/licenses/>. + +Positive feedback controller for a discrete-time system (D == 0). +Uses SLICOT SB10KD by courtesy of NICONET e.V. +<http://www.slicot.org> + +Author: Lukas Reichlin <lukas.reichlin@gmail.com> +Created: July 2011 +Version: 0.1 + +*/ + +#include <octave/oct.h> +#include <f77-fcn.h> +#include "common.cc" + +extern "C" +{ + int F77_FUNC (sb10kd, SB10KD) + (int& N, int& M, int& NP, + double* A, int& LDA, + double* B, int& LDB, + double* C, int& LDC, + double& FACTOR, + double* AK, int& LDAK, + double* BK, int& LDBK, + double* CK, int& LDCK, + double* DK, int& LDDK, + double* RCOND, + int* IWORK, + double* DWORK, int& LDWORK, + bool* BWORK, + int& INFO); +} + +DEFUN_DLD (slsb10kd, args, nargout, + "-*- texinfo -*-\n\ +Slicot SB10KD Release 5.0\n\ +No argument checking.\n\ +For internal use only.") +{ + int nargin = args.length (); + octave_value_list retval; + + if (nargin != 4) + { + print_usage (); + } + else + { + // arguments in + Matrix a = args(0).matrix_value (); + Matrix b = args(1).matrix_value (); + Matrix c = args(2).matrix_value (); + + double factor = args(3).double_value (); + + int n = a.rows (); // n: number of states + int m = b.columns (); // m: number of inputs + int np = c.rows (); // np: number of outputs + + int lda = max (1, n); + int ldb = max (1, n); + int ldc = max (1, np); + + int ldak = max (1, n); + int ldbk = max (1, n); + int ldck = max (1, m); + int lddk = max (1, m); + + // arguments out + int nk; + Matrix ak (ldak, n); + Matrix bk (ldbk, np); + Matrix ck (ldck, n); + Matrix dk (lddk, np); + ColumnVector rcond (4); + + // workspace + int liwork = 2 * max (n, np+m); + int ldwork = 15*n*n + 6*n + + max (14*n+23, 16*n, 2*n+np+m, 3*(np+m)) + + max (n*n, 11*n*np + 2*m*m + 8*np*np + 8*m*n + 4*m*np + np); + + OCTAVE_LOCAL_BUFFER (int, iwork, liwork); + OCTAVE_LOCAL_BUFFER (double, dwork, ldwork); + OCTAVE_LOCAL_BUFFER (bool, bwork, 2*n); + + // error indicator + int info; + + + // SLICOT routine SB10KD + F77_XFCN (sb10kd, SB10KD, + (n, m, np, + a.fortran_vec (), lda, + b.fortran_vec (), ldb, + c.fortran_vec (), ldc, + factor, + ak.fortran_vec (), ldak, + bk.fortran_vec (), ldbk, + ck.fortran_vec (), ldck, + dk.fortran_vec (), lddk, + rcond.fortran_vec (), + iwork, + dwork, ldwork, + bwork, + info)); + + if (f77_exception_encountered) + error ("hinfsyn: slsb10kd: exception in SLICOT subroutine SB10KD"); + + if (info != 0) + error ("hinfsyn: slsb10kd: SB10KD returned info = %d", info); + + // resizing + ak.resize (n, n); + bk.resize (n, np); + ck.resize (m, n); + dk.resize (m, np); + + // return values + retval(0) = ak; + retval(1) = bk; + retval(2) = ck; + retval(3) = dk; + retval(4) = rcond; + } + + return retval; +}