SUBROUTINE AB8NXZ( N, M, P, RO, SIGMA, SVLMAX, ABCD, LDABCD, $ NINFZ, INFZ, KRONL, MU, NU, NKROL, TOL, IWORK, $ DWORK, ZWORK, LZWORK, INFO ) C C SLICOT RELEASE 5.0. C C Copyright (c) 2002-2009 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 . C C PURPOSE C C To extract from the (N+P)-by-(M+N) system C ( B A ) C ( D C ) C an (NU+MU)-by-(M+NU) "reduced" system C ( B' A') C ( D' C') C having the same transmission zeros but with D' of full row rank. C C ARGUMENTS C C Input/Output Parameters C C N (input) INTEGER C The number of state variables. N >= 0. C C M (input) INTEGER C The number of system inputs. M >= 0. C C P (input) INTEGER C The number of system outputs. P >= 0. C C RO (input/output) INTEGER C On entry, C = P for the original system; C = MAX(P-M, 0) for the pertransposed system. C On exit, RO contains the last computed rank. C C SIGMA (input/output) INTEGER C On entry, C = 0 for the original system; C = M for the pertransposed system. C On exit, SIGMA contains the last computed value sigma in C the algorithm. C C SVLMAX (input) DOUBLE PRECISION C During each reduction step, the rank-revealing QR C factorization of a matrix stops when the estimated minimum C singular value is smaller than TOL * MAX(SVLMAX,EMSV), C where EMSV is the estimated maximum singular value. C SVLMAX >= 0. C C ABCD (input/output) COMPLEX*16 array, dimension (LDABCD,M+N) C On entry, the leading (N+P)-by-(M+N) part of this array C must contain the compound input matrix of the system. C On exit, the leading (NU+MU)-by-(M+NU) part of this array C contains the reduced compound input matrix of the system. C C LDABCD INTEGER C The leading dimension of array ABCD. C LDABCD >= MAX(1,N+P). C C NINFZ (input/output) INTEGER C On entry, the currently computed number of infinite zeros. C It should be initialized to zero on the first call. C NINFZ >= 0. C On exit, the number of infinite zeros. C C INFZ (input/output) INTEGER array, dimension (N) C On entry, INFZ(i) must contain the current number of C infinite zeros of degree i, where i = 1,2,...,N, found in C the previous call(s) of the routine. It should be C initialized to zero on the first call. C On exit, INFZ(i) contains the number of infinite zeros of C degree i, where i = 1,2,...,N. C C KRONL (input/output) INTEGER array, dimension (N+1) C On entry, this array must contain the currently computed C left Kronecker (row) indices found in the previous call(s) C of the routine. It should be initialized to zero on the C first call. C On exit, the leading NKROL elements of this array contain C the left Kronecker (row) indices. C C MU (output) INTEGER C The normal rank of the transfer function matrix of the C original system. C C NU (output) INTEGER C The dimension of the reduced system matrix and the number C of (finite) invariant zeros if D' is invertible. C C NKROL (output) INTEGER C The number of left Kronecker indices. C C Tolerances C C TOL DOUBLE PRECISION C A tolerance used in rank decisions to determine the C effective rank, which is defined as the order of the C largest leading (or trailing) triangular submatrix in the C QR (or RQ) factorization with column (or row) pivoting C whose estimated condition number is less than 1/TOL. C NOTE that when SVLMAX > 0, the estimated ranks could be C less than those defined above (see SVLMAX). C C Workspace C C IWORK INTEGER array, dimension (MAX(M,P)) C C DWORK DOUBLE PRECISION array, dimension (2*MAX(M,P)) C C ZWORK COMPLEX*16 array, dimension (LZWORK) C On exit, if INFO = 0, ZWORK(1) returns the optimal value C of LZWORK. C C LZWORK INTEGER C The length of the array ZWORK. C LZWORK >= MAX( 1, MIN(P,M) + MAX(3*M-1,N), C MIN(P,N) + MAX(3*P-1,N+P,N+M) ). C For optimum performance LZWORK should be larger. C C If LZWORK = -1, then a workspace query is assumed; C the routine only calculates the optimal size of the C ZWORK array, returns this value as the first entry of C the ZWORK array, and no error message related to LZWORK C is issued by XERBLA. 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 C REFERENCES C C [1] Svaricek, F. C Computation of the Structural Invariants of Linear C Multivariable Systems with an Extended Version of C the Program ZEROS. C System & Control Letters, 6, pp. 261-266, 1985. C C [2] Emami-Naeini, A. and Van Dooren, P. C Computation of Zeros of Linear Multivariable Systems. C Automatica, 18, pp. 415-430, 1982. C C NUMERICAL ASPECTS C C The algorithm is backward stable. C C CONTRIBUTOR C C V. Sima, Katholieke Univ. Leuven, Belgium, Nov. 1996. C Complex version: V. Sima, Research Institute for Informatics, C Bucharest, Nov. 2008 with suggestions from P. Gahinet, C The MathWorks. C C REVISIONS C C V. Sima, Research Institute for Informatics, Bucharest, Apr. 2009. C C KEYWORDS C C Generalized eigenvalue problem, Kronecker indices, multivariable C system, unitary transformation, structural invariant. C C ****************************************************************** C C .. Parameters .. COMPLEX*16 ZERO PARAMETER ( ZERO = ( 0.0D+0, 0.0D+0 ) ) DOUBLE PRECISION DZERO PARAMETER ( DZERO = 0.0D0 ) C .. Scalar Arguments .. INTEGER INFO, LDABCD, LZWORK, M, MU, N, NINFZ, NKROL, $ NU, P, RO, SIGMA DOUBLE PRECISION SVLMAX, TOL C .. Array Arguments .. INTEGER INFZ(*), IWORK(*), KRONL(*) COMPLEX*16 ABCD(LDABCD,*), ZWORK(*) DOUBLE PRECISION DWORK(*) C .. Local Scalars .. LOGICAL LQUERY INTEGER I1, IK, IROW, ITAU, IZ, JWORK, MM1, MNTAU, MNU, $ MPM, NB, NP, RANK, RO1, TAU, WRKOPT COMPLEX*16 TC C .. Local Arrays .. DOUBLE PRECISION SVAL(3) C .. External Functions .. INTEGER ILAENV EXTERNAL ILAENV C .. External Subroutines .. EXTERNAL MB3OYZ, MB3PYZ, XERBLA, ZLAPMT, ZLARFG, ZLASET, $ ZLATZM, ZUNMQR, ZUNMRQ C .. Intrinsic Functions .. INTRINSIC DCONJG, INT, MAX, MIN C .. Executable Statements .. C NP = N + P MPM = MIN( P, M ) INFO = 0 LQUERY = ( LZWORK.EQ.-1 ) C C Test the input scalar arguments. C IF( N.LT.0 ) THEN INFO = -1 ELSE IF( M.LT.0 ) THEN INFO = -2 ELSE IF( P.LT.0 ) THEN INFO = -3 ELSE IF( RO.NE.P .AND. RO.NE.MAX( P-M, 0 ) ) THEN INFO = -4 ELSE IF( SIGMA.NE.0 .AND. SIGMA.NE.M ) THEN INFO = -5 ELSE IF( SVLMAX.LT.DZERO ) THEN INFO = -6 ELSE IF( LDABCD.LT.MAX( 1, NP ) ) THEN INFO = -8 ELSE IF( NINFZ.LT.0 ) THEN INFO = -9 ELSE JWORK = MAX( 1, MPM + MAX( 3*M - 1, N ), $ MIN( P, N ) + MAX( 3*P - 1, NP, N+M ) ) IF( LQUERY ) THEN IF( M.GT.0 ) THEN NB = MIN( 64, ILAENV( 1, 'ZUNMQR', 'LC', P, N, MPM, $ -1 ) ) WRKOPT = MAX( JWORK, MPM + MAX( 1, N )*NB ) ELSE WRKOPT = JWORK END IF NB = MIN( 64, ILAENV( 1, 'ZUNMRQ', 'RC', NP, N, MIN( P, N ), $ -1 ) ) WRKOPT = MAX( WRKOPT, MIN( P, N ) + MAX( 1, NP )*NB ) NB = MIN( 64, ILAENV( 1, 'ZUNMRQ', 'LN', N, M+N, $ MIN( P, N ), -1 ) ) WRKOPT = MAX( WRKOPT, MIN( P, N ) + MAX( 1, M+N )*NB ) ELSE IF( LZWORK.LT.JWORK ) THEN INFO = -19 END IF END IF C IF ( INFO.NE.0 ) THEN C C Error return. C CALL XERBLA( 'AB8NXZ', -INFO ) RETURN ELSE IF( LQUERY ) THEN ZWORK(1) = WRKOPT RETURN END IF C MU = P NU = N C IZ = 0 IK = 1 MM1 = M + 1 ITAU = 1 NKROL = 0 WRKOPT = 1 C C Main reduction loop: C C M NU M NU C NU [ B A ] NU [ B A ] C MU [ D C ] --> SIGMA [ RD C1 ] (SIGMA = rank(D) = C TAU [ 0 C2 ] row size of RD) C C M NU-RO RO C NU-RO [ B1 A11 A12 ] C --> RO [ B2 A21 A22 ] (RO = rank(C2) = C SIGMA [ RD C11 C12 ] col size of LC) C TAU [ 0 0 LC ] C C M NU-RO C NU-RO [ B1 A11 ] NU := NU - RO C [----------] MU := RO + SIGMA C --> RO [ B2 A21 ] D := [B2;RD] C SIGMA [ RD C11 ] C := [A21;C11] C 20 IF ( MU.EQ.0 ) $ GO TO 80 C C (Note: Comments in the code beginning "xWorkspace:", where x is C I, D, or C, describe the minimal amount of integer, real and C complex workspace needed at that point in the code, respectively, C as well as the preferred amount for good performance.) C RO1 = RO MNU = M + NU IF ( M.GT.0 ) THEN IF ( SIGMA.NE.0 ) THEN IROW = NU + 1 C C Compress rows of D. First exploit triangular shape. C CWorkspace: need M+N-1. C DO 40 I1 = 1, SIGMA CALL ZLARFG( RO+1, ABCD(IROW,I1), ABCD(IROW+1,I1), 1, $ TC ) CALL ZLATZM( 'L', RO+1, MNU-I1, ABCD(IROW+1,I1), 1, $ DCONJG( TC ), ABCD(IROW,I1+1), $ ABCD(IROW+1,I1+1), LDABCD, ZWORK ) IROW = IROW + 1 40 CONTINUE CALL ZLASET( 'Lower', RO+SIGMA-1, SIGMA, ZERO, ZERO, $ ABCD(NU+2,1), LDABCD ) END IF C C Continue with Householder with column pivoting. C C The rank of D is the number of (estimated) singular values C that are greater than TOL * MAX(SVLMAX,EMSV). This number C includes the singular values of the first SIGMA columns. C IWorkspace: need M; C RWorkspace: need 2*M; C CWorkspace: need min(RO1,M) + 3*M - 1. RO1 <= P. C IF ( SIGMA.LT.M ) THEN JWORK = ITAU + MIN( RO1, M ) I1 = SIGMA + 1 IROW = NU + I1 CALL MB3OYZ( RO1, M-SIGMA, ABCD(IROW,I1), LDABCD, TOL, $ SVLMAX, RANK, SVAL, IWORK, ZWORK(ITAU), DWORK, $ ZWORK(JWORK), INFO ) WRKOPT = MAX( WRKOPT, JWORK + 3*M - 2 ) C C Apply the column permutations to matrices B and part of D. C CALL ZLAPMT( .TRUE., NU+SIGMA, M-SIGMA, ABCD(1,I1), LDABCD, $ IWORK ) C IF ( RANK.GT.0 ) THEN C C Apply the Householder transformations to the submatrix C. C CWorkspace: need min(RO1,M) + NU; C prefer min(RO1,M) + NU*NB. C CALL ZUNMQR( 'Left', 'Conjugate', RO1, NU, RANK, $ ABCD(IROW,I1), LDABCD, ZWORK(ITAU), $ ABCD(IROW,MM1), LDABCD, ZWORK(JWORK), $ LZWORK-JWORK+1, INFO ) WRKOPT = MAX( WRKOPT, INT( ZWORK(JWORK) ) + JWORK - 1 ) IF ( RO1.GT.1 ) $ CALL ZLASET( 'Lower', RO1-1, MIN( RO1-1, RANK ), ZERO, $ ZERO, ABCD(IROW+1,I1), LDABCD ) RO1 = RO1 - RANK END IF END IF END IF C TAU = RO1 SIGMA = MU - TAU C C Determination of the orders of the infinite zeros. C IF ( IZ.GT.0 ) THEN INFZ(IZ) = INFZ(IZ) + RO - TAU NINFZ = NINFZ + IZ*( RO - TAU ) END IF IF ( RO1.EQ.0 ) $ GO TO 80 IZ = IZ + 1 C IF ( NU.LE.0 ) THEN MU = SIGMA NU = 0 RO = 0 ELSE C C Compress the columns of C2 using RQ factorization with row C pivoting, P * C2 = R * Q. C I1 = NU + SIGMA + 1 MNTAU = MIN( TAU, NU ) JWORK = ITAU + MNTAU C C The rank of C2 is the number of (estimated) singular values C greater than TOL * MAX(SVLMAX,EMSV). C IWorkspace: need TAU; C RWorkspace: need 2*TAU; C CWorkspace: need min(TAU,NU) + 3*TAU - 1. C CALL MB3PYZ( TAU, NU, ABCD(I1,MM1), LDABCD, TOL, SVLMAX, RANK, $ SVAL, IWORK, ZWORK(ITAU), DWORK, ZWORK(JWORK), $ INFO ) WRKOPT = MAX( WRKOPT, JWORK + 3*TAU - 1 ) IF ( RANK.GT.0 ) THEN IROW = I1 + TAU - RANK C C Apply Q' to the first NU columns of [A; C1] from the right. C CWorkspace: need min(TAU,NU) + NU + SIGMA; SIGMA <= P; C prefer min(TAU,NU) + (NU + SIGMA)*NB. C CALL ZUNMRQ( 'Right', 'ConjTranspose', I1-1, NU, RANK, $ ABCD(IROW,MM1), LDABCD, ZWORK(MNTAU-RANK+1), $ ABCD(1,MM1), LDABCD, ZWORK(JWORK), $ LZWORK-JWORK+1, INFO ) WRKOPT = MAX( WRKOPT, INT( ZWORK(JWORK) ) + JWORK - 1 ) C C Apply Q to the first NU rows and M + NU columns of [ B A ] C from the left. C CWorkspace: need min(TAU,NU) + M + NU; C prefer min(TAU,NU) + (M + NU)*NB. C CALL ZUNMRQ( 'Left', 'NoTranspose', NU, MNU, RANK, $ ABCD(IROW,MM1), LDABCD, ZWORK(MNTAU-RANK+1), $ ABCD, LDABCD, ZWORK(JWORK), LZWORK-JWORK+1, $ INFO ) WRKOPT = MAX( WRKOPT, INT( ZWORK(JWORK) ) + JWORK - 1 ) C CALL ZLASET( 'Full', RANK, NU-RANK, ZERO, ZERO, $ ABCD(IROW,MM1), LDABCD ) IF ( RANK.GT.1 ) $ CALL ZLASET( 'Lower', RANK-1, RANK-1, ZERO, ZERO, $ ABCD(IROW+1,MM1+NU-RANK), LDABCD ) END IF C RO = RANK END IF C C Determine the left Kronecker indices (row indices). C KRONL(IK) = KRONL(IK) + TAU - RO NKROL = NKROL + KRONL(IK) IK = IK + 1 C C C and D are updated to [A21 ; C11] and [B2 ; RD]. C NU = NU - RO MU = SIGMA + RO IF ( RO.NE.0 ) $ GO TO 20 C 80 CONTINUE ZWORK(1) = WRKOPT RETURN C *** Last line of AB8NXZ *** END