changeset 9463:c44337093f26 octave-forge

control-devel: reorganize makefile
author paramaniac
date Wed, 22 Feb 2012 16:37:14 +0000
parents 01fc7045de79
children 1bfbb147cb14
files extra/control-devel/devel/makefile_modred.m extra/control-devel/src/AB04MD.f extra/control-devel/src/AB05PD.f extra/control-devel/src/AB05QD.f extra/control-devel/src/AB07MD.f extra/control-devel/src/AB07ND.f extra/control-devel/src/AB08MD.f extra/control-devel/src/AB08NX.f extra/control-devel/src/AB09AD.f extra/control-devel/src/AB09AX.f extra/control-devel/src/AB09BD.f extra/control-devel/src/AB09BX.f extra/control-devel/src/AB09CX.f extra/control-devel/src/AB09DD.f extra/control-devel/src/AB09HD.f extra/control-devel/src/AB09HY.f extra/control-devel/src/AB09ID.f extra/control-devel/src/AB09IX.f extra/control-devel/src/AB09IY.f extra/control-devel/src/AB09JD.f extra/control-devel/src/AB09JV.f extra/control-devel/src/AB09JW.f extra/control-devel/src/AB09JX.f extra/control-devel/src/AG07BD.f extra/control-devel/src/DG01MD.f extra/control-devel/src/IB01AD.f extra/control-devel/src/IB01BD.f extra/control-devel/src/IB01CD.f extra/control-devel/src/IB01MD.f extra/control-devel/src/IB01MY.f extra/control-devel/src/IB01ND.f extra/control-devel/src/IB01OD.f extra/control-devel/src/IB01OY.f extra/control-devel/src/IB01PD.f extra/control-devel/src/IB01PX.f extra/control-devel/src/IB01PY.f extra/control-devel/src/IB01QD.f extra/control-devel/src/IB01RD.f extra/control-devel/src/MA02AD.f extra/control-devel/src/MA02BD.f extra/control-devel/src/MA02DD.f extra/control-devel/src/MA02ED.f extra/control-devel/src/MA02FD.f extra/control-devel/src/MA02GD.f extra/control-devel/src/MB01PD.f extra/control-devel/src/MB01QD.f extra/control-devel/src/MB01RU.f extra/control-devel/src/MB01RX.f extra/control-devel/src/MB01RY.f extra/control-devel/src/MB01SD.f extra/control-devel/src/MB01TD.f extra/control-devel/src/MB01UD.f extra/control-devel/src/MB01VD.f extra/control-devel/src/MB01WD.f extra/control-devel/src/MB01YD.f extra/control-devel/src/MB01ZD.f extra/control-devel/src/MB02PD.f extra/control-devel/src/MB02QY.f extra/control-devel/src/MB02UD.f extra/control-devel/src/MB03OD.f extra/control-devel/src/MB03OY.f extra/control-devel/src/MB03PY.f extra/control-devel/src/MB03QD.f extra/control-devel/src/MB03QX.f extra/control-devel/src/MB03QY.f extra/control-devel/src/MB03UD.f extra/control-devel/src/MB04ID.f extra/control-devel/src/MB04IY.f extra/control-devel/src/MB04KD.f extra/control-devel/src/MB04ND.f extra/control-devel/src/MB04NY.f extra/control-devel/src/MB04OD.f extra/control-devel/src/MB04OX.f extra/control-devel/src/MB04OY.f extra/control-devel/src/MC01PD.f extra/control-devel/src/Makefile extra/control-devel/src/SB01FY.f extra/control-devel/src/SB02MD.f extra/control-devel/src/SB02MR.f extra/control-devel/src/SB02MS.f extra/control-devel/src/SB02MT.f extra/control-devel/src/SB02MU.f extra/control-devel/src/SB02MV.f extra/control-devel/src/SB02MW.f extra/control-devel/src/SB02ND.f extra/control-devel/src/SB02QD.f extra/control-devel/src/SB02RD.f extra/control-devel/src/SB02RU.f extra/control-devel/src/SB02SD.f extra/control-devel/src/SB03MV.f extra/control-devel/src/SB03MW.f extra/control-devel/src/SB03MX.f extra/control-devel/src/SB03MY.f extra/control-devel/src/SB03OD.f extra/control-devel/src/SB03OR.f extra/control-devel/src/SB03OT.f extra/control-devel/src/SB03OU.f extra/control-devel/src/SB03OV.f extra/control-devel/src/SB03OY.f extra/control-devel/src/SB03QX.f extra/control-devel/src/SB03QY.f extra/control-devel/src/SB03SX.f extra/control-devel/src/SB03SY.f extra/control-devel/src/SB04PX.f extra/control-devel/src/SB04PY.f extra/control-devel/src/SB08CD.f extra/control-devel/src/SB08DD.f extra/control-devel/src/SB08GD.f extra/control-devel/src/SB08HD.f extra/control-devel/src/SB10YD.f extra/control-devel/src/SB10ZP.f extra/control-devel/src/SB16AD.f extra/control-devel/src/SB16AY.f extra/control-devel/src/SB16BD.f extra/control-devel/src/SB16CD.f extra/control-devel/src/SB16CY.f extra/control-devel/src/TB01ID.f extra/control-devel/src/TB01KD.f extra/control-devel/src/TB01LD.f extra/control-devel/src/TB01PD.f extra/control-devel/src/TB01UD.f extra/control-devel/src/TB01WD.f extra/control-devel/src/TB01XD.f extra/control-devel/src/TD03AY.f extra/control-devel/src/TD04AD.f extra/control-devel/src/delctg.f extra/control-devel/src/select.f extra/control-devel/src/slicot.tar.gz
diffstat 128 files changed, 27 insertions(+), 58689 deletions(-) [+]
line wrap: on
line diff
--- a/extra/control-devel/devel/makefile_modred.m	Wed Feb 22 15:13:45 2012 +0000
+++ b/extra/control-devel/devel/makefile_modred.m	Wed Feb 22 16:37:14 2012 +0000
@@ -13,36 +13,17 @@
 cd (srcdir);
 
 mkoctfile slab09hd.cc \
-          AB09HD.f TB01ID.f AB04MD.f TB01KD.f AB09HY.f \
-          AB09IX.f MB03UD.f SB02MD.f AB09DD.f TB01LD.f \
-          SB03OU.f MA02AD.f MB03QX.f select.f SB03OT.f \
-          SB02MR.f SB02MS.f MB03QD.f SB02MU.f SB02MV.f \
-          SB02MW.f MB04ND.f MB04OD.f MB03QY.f SB03OR.f \
-          SB03OY.f SB04PX.f MB04NY.f MB04OY.f SB03OV.f \
+          slicotlibrary.a \
           "$(mkoctfile -p LAPACK_LIBS)" \
           "$(mkoctfile -p BLAS_LIBS)"
 
 mkoctfile slab09id.cc \
-          AB09ID.f TB01PD.f SB08DD.f TB01ID.f TB01KD.f \
-          AB09IX.f AB09IY.f SB08CD.f MB04ND.f TB01XD.f \
-          MB04OD.f MB01WD.f MB03UD.f AB07MD.f SB01FY.f \
-          AB09DD.f TB01LD.f SB03OU.f TB01UD.f MA02AD.f \
-          MA02BD.f MB03OY.f MB03QX.f MB01PD.f select.f \
-          MB01YD.f MB04NY.f MB01ZD.f SB03OT.f MB04OX.f \
-          MB04OY.f MB03QD.f SB03OY.f MB03QY.f MB01QD.f \
-          SB03OR.f SB03OV.f SB04PX.f \
+          slicotlibrary.a \
           "$(mkoctfile -p LAPACK_LIBS)" \
           "$(mkoctfile -p BLAS_LIBS)"
 
 mkoctfile slab09jd.cc \
-          AB09JD.f TB01ID.f TB01KD.f AB07ND.f AB09JV.f \
-          AB09JW.f AB09CX.f AG07BD.f AB08MD.f AB04MD.f \
-          TB01LD.f delctg.f SB04PY.f AB09AX.f AB08NX.f \
-          MB01SD.f AB09JX.f MA02AD.f TB01WD.f MB03OY.f \
-          MB03PY.f MA02DD.f MB03UD.f MB03QX.f select.f \
-          SB04PX.f SB03OU.f MB03QD.f MB03QY.f SB03OT.f \
-          MB04ND.f MB04OD.f SB03OR.f SB03OY.f MB04NY.f \
-          MB04OY.f SB03OV.f \
+          slicotlibrary.a \
           "$(mkoctfile -p LAPACK_LIBS)" \
           "$(mkoctfile -p BLAS_LIBS)"
 
--- a/extra/control-devel/src/AB04MD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,345 +0,0 @@
-      SUBROUTINE AB04MD( TYPE, N, M, P, ALPHA, BETA, A, LDA, B, LDB, C,
-     $                   LDC, D, LDD, IWORK, DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To perform a transformation on the parameters (A,B,C,D) of a
-C     system, which is equivalent to a bilinear transformation of the
-C     corresponding transfer function matrix.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     TYPE    CHARACTER*1
-C             Indicates the type of the original system and the
-C             transformation to be performed as follows:
-C             = 'D':  discrete-time   -> continuous-time;
-C             = 'C':  continuous-time -> discrete-time.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the state matrix A.  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     ALPHA,  (input) DOUBLE PRECISION
-C     BETA    Parameters specifying the bilinear transformation.
-C             Recommended values for stable systems: ALPHA = 1,
-C             BETA = 1.  ALPHA <> 0, BETA <> 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state matrix A of the original system.
-C             On exit, the leading N-by-N part of this array contains
-C                              _
-C             the state matrix A of the transformed system.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input matrix B of the original system.
-C             On exit, the leading N-by-M part of this array contains
-C                              _
-C             the input matrix B of the transformed system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the output matrix C of the original system.
-C             On exit, the leading P-by-N part of this array contains
-C                               _
-C             the output matrix C of the transformed system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the input/output matrix D for the original system.
-C             On exit, the leading P-by-M part of this array contains
-C                                     _
-C             the input/output matrix D of the transformed system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.  LDWORK >= MAX(1,N).
-C             For optimum performance LDWORK >= MAX(1,N*NB), where NB
-C             is the optimal blocksize.
-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 matrix (ALPHA*I + A) is exactly singular;
-C             = 2:  if the matrix  (BETA*I - A) is exactly singular.
-C
-C     METHOD
-C
-C     The parameters of the discrete-time system are transformed into
-C     the parameters of the continuous-time system (TYPE = 'D'), or
-C     vice-versa (TYPE = 'C') by the transformation:
-C
-C     1.  Discrete -> continuous
-C         _                     -1
-C         A = beta*(alpha*I + A)  * (A - alpha*I)
-C         _                                     -1
-C         B = sqrt(2*alpha*beta) * (alpha*I + A)  * B
-C         _                                         -1
-C         C = sqrt(2*alpha*beta) * C * (alpha*I + A)
-C         _                        -1
-C         D = D - C * (alpha*I + A)  * B
-C
-C     which is equivalent to the bilinear transformation
-C
-C                       z - alpha
-C         z -> s = beta ---------  .
-C                       z + alpha
-C
-C     of one transfer matrix onto the other.
-C
-C     2.  Continuous -> discrete
-C         _                     -1
-C         A = alpha*(beta*I - A)  * (beta*I + A)
-C         _                                    -1
-C         B = sqrt(2*alpha*beta) * (beta*I - A)  * B
-C         _                                        -1
-C         C = sqrt(2*alpha*beta) * C * (beta*I - A)
-C         _                       -1
-C         D = D + C * (beta*I - A)  * B
-C
-C     which is equivalent to the bilinear transformation
-C
-C                      beta + s
-C       s -> z = alpha -------- .
-C                      beta - s
-C
-C     of one transfer matrix onto the other.
-C
-C     REFERENCES
-C
-C     [1] Al-Saggaf, U.M. and Franklin, G.F.
-C         Model reduction via balanced realizations: a extension and
-C         frequency weighting techniques.
-C         IEEE Trans. Autom. Contr., AC-33, pp. 687-692, 1988.
-C
-C     NUMERICAL ASPECTS
-C                                                      3
-C     The time taken is approximately proportional to N .
-C     The accuracy depends mainly on the condition number of the matrix
-C     to be inverted.
-C
-C     CONTRIBUTORS
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, and
-C                  A. Varga, German Aerospace Research Establishment,
-C                  Oberpfaffenhofen, Germany, Nov. 1996.
-C     Supersedes Release 2.0 routine AB04AD by W. van der Linden, and
-C     A.J. Geurts, Technische Hogeschool Eindhoven, Holland.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Bilinear transformation, continuous-time system, discrete-time
-C     system, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE, TWO
-      PARAMETER         ( ZERO=0.0D0, ONE=1.0D0, TWO=2.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         TYPE
-      INTEGER           INFO, LDA, LDB, LDC, LDD, LDWORK, M, N, P
-      DOUBLE PRECISION  ALPHA, BETA
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*), DWORK(*)
-C     .. Local Scalars ..
-      LOGICAL           LTYPE
-      INTEGER           I, IP
-      DOUBLE PRECISION  AB2, PALPHA, PBETA, SQRAB2
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DGEMM, DGETRF, DGETRS, DGETRI, DLASCL, DSCAL,
-     $                  DSWAP, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         ABS, MAX, SIGN, SQRT
-C     .. Executable Statements ..
-C
-      INFO = 0
-      LTYPE = LSAME( TYPE, 'D' )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.LTYPE .AND. .NOT.LSAME( TYPE, 'C' ) ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( ALPHA.EQ.ZERO ) THEN
-         INFO = -5
-      ELSE IF( BETA.EQ.ZERO ) THEN
-         INFO = -6
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -10
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -12
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -14
-      ELSE IF( LDWORK.LT.MAX( 1, N ) ) THEN
-         INFO = -17
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB04MD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( MAX( N, M, P ).EQ.0 )
-     $   RETURN
-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 (LTYPE) THEN
-C
-C        Discrete-time to continuous-time with (ALPHA, BETA).
-C
-         PALPHA = ALPHA
-         PBETA = BETA
-      ELSE
-C
-C        Continuous-time to discrete-time with (ALPHA, BETA) is
-C        equivalent with discrete-time to continuous-time with
-C        (-BETA, -ALPHA), if B and C change the sign.
-C
-         PALPHA = -BETA
-         PBETA = -ALPHA
-      END IF
-C
-      AB2 = PALPHA*PBETA*TWO
-      SQRAB2 = SIGN( SQRT( ABS( AB2 ) ), PALPHA )
-C                          -1
-C     Compute (alpha*I + A)  .
-C
-      DO 10 I = 1, N
-         A(I,I)  =  A(I,I) + PALPHA
-   10 CONTINUE
-C
-      CALL DGETRF( N, N, A, LDA, IWORK, INFO )
-C
-      IF (INFO.NE.0) THEN
-C
-C        Error return.
-C
-         IF (LTYPE) THEN
-            INFO = 1
-         ELSE
-            INFO = 2
-         END IF
-         RETURN
-      END IF
-C                         -1
-C     Compute  (alpha*I+A)  *B.
-C
-      CALL DGETRS( 'No transpose', N, M, A, LDA, IWORK, B, LDB, INFO )
-C                               -1
-C     Compute  D - C*(alpha*I+A)  *B.
-C
-      CALL DGEMM( 'No transpose', 'No transpose', P, M, N, -ONE, C,
-     $            LDC, B, LDB, ONE, D, LDD )
-C
-C     Scale B by  sqrt(2*alpha*beta).
-C
-      CALL DLASCL( 'General', 0, 0, ONE, SQRAB2, N, M, B, LDB, INFO )
-C                                                -1
-C     Compute  sqrt(2*alpha*beta)*C*(alpha*I + A)  .
-C
-      CALL DTRSM( 'Right', 'Upper', 'No transpose', 'Non-unit', P, N,
-     $            SQRAB2, A, LDA, C, LDC )
-C
-      CALL DTRSM( 'Right', 'Lower', 'No transpose', 'Unit', P, N, ONE,
-     $            A, LDA, C, LDC )
-C
-C     Apply column interchanges to the solution matrix.
-C
-      DO 20 I = N-1, 1, -1
-         IP = IWORK(I)
-         IF ( IP.NE.I )
-     $      CALL DSWAP( P, C(1,I), 1, C(1,IP), 1 )
-  20  CONTINUE
-C                               -1
-C     Compute beta*(alpha*I + A)  *(A - alpha*I) as
-C                                        -1
-C     beta*I - 2*alpha*beta*(alpha*I + A)  .
-C
-C     Workspace: need N;  prefer N*NB.
-C
-      CALL DGETRI( N, A, LDA, IWORK, DWORK, LDWORK, INFO )
-C
-      DO 30 I = 1, N
-         CALL DSCAL(N, -AB2, A(1,I), 1)
-         A(I,I) = A(I,I) + PBETA
-   30 CONTINUE
-C
-      RETURN
-C *** Last line of AB04MD ***
-      END
--- a/extra/control-devel/src/AB05PD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,385 +0,0 @@
-      SUBROUTINE AB05PD( OVER, N1, M, P, N2, ALPHA, A1, LDA1, B1, LDB1,
-     $                   C1, LDC1, D1, LDD1, A2, LDA2, B2, LDB2, C2,
-     $                   LDC2, D2, LDD2, N, A, LDA, B, LDB, C, LDC, D,
-     $                   LDD, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the state-space model G = (A,B,C,D) corresponding to
-C     the sum G = G1 + alpha*G2, where G1 = (A1,B1,C1,D1) and
-C     G2 = (A2,B2,C2,D2).  G, G1, and G2 are the transfer-function
-C     matrices of the corresponding state-space models.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     OVER    CHARACTER*1
-C             Indicates whether the user wishes to overlap pairs of
-C             arrays, as follows:
-C             = 'N':  Do not overlap;
-C             = 'O':  Overlap pairs of arrays: A1 and A, B1 and B,
-C                     C1 and C, and D1 and D, i.e. the same name is
-C                     effectively used for each pair (for all pairs)
-C                     in the routine call.  In this case, setting
-C                     LDA1 = LDA, LDB1 = LDB, LDC1 = LDC, and LDD1 = LDD
-C                     will give maximum efficiency.
-C
-C     Input/Output Parameters
-C
-C     N1      (input) INTEGER
-C             The number of state variables in the first system, i.e.
-C             the order of the matrix A1, the number of rows of B1 and
-C             the number of columns of C1.  N1 >= 0.
-C
-C     M       (input) INTEGER
-C             The number of input variables of the two systems, i.e. the
-C             number of columns of matrices B1, D1, B2 and D2.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The number of output variables of the two systems, i.e.
-C             the number of rows of matrices C1, D1, C2 and D2.  P >= 0.
-C
-C     N2      (input) INTEGER
-C             The number of state variables in the second system, i.e.
-C             the order of the matrix A2, the number of rows of B2 and
-C             the number of columns of C2.  N2 >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The coefficient multiplying G2.
-C
-C     A1      (input) DOUBLE PRECISION array, dimension (LDA1,N1)
-C             The leading N1-by-N1 part of this array must contain the
-C             state transition matrix A1 for the first system.
-C
-C     LDA1    INTEGER
-C             The leading dimension of array A1.  LDA1 >= MAX(1,N1).
-C
-C     B1      (input) DOUBLE PRECISION array, dimension (LDB1,M)
-C             The leading N1-by-M part of this array must contain the
-C             input/state matrix B1 for the first system.
-C
-C     LDB1    INTEGER
-C             The leading dimension of array B1.  LDB1 >= MAX(1,N1).
-C
-C     C1      (input) DOUBLE PRECISION array, dimension (LDC1,N1)
-C             The leading P-by-N1 part of this array must contain the
-C             state/output matrix C1 for the first system.
-C
-C     LDC1    INTEGER
-C             The leading dimension of array C1.
-C             LDC1 >= MAX(1,P) if N1 > 0.
-C             LDC1 >= 1 if N1 = 0.
-C
-C     D1      (input) DOUBLE PRECISION array, dimension (LDD1,M)
-C             The leading P-by-M part of this array must contain the
-C             input/output matrix D1 for the first system.
-C
-C     LDD1    INTEGER
-C             The leading dimension of array D1.  LDD1 >= MAX(1,P).
-C
-C     A2      (input) DOUBLE PRECISION array, dimension (LDA2,N2)
-C             The leading N2-by-N2 part of this array must contain the
-C             state transition matrix A2 for the second system.
-C
-C     LDA2    INTEGER
-C             The leading dimension of array A2.  LDA2 >= MAX(1,N2).
-C
-C     B2      (input) DOUBLE PRECISION array, dimension (LDB2,M)
-C             The leading N2-by-M part of this array must contain the
-C             input/state matrix B2 for the second system.
-C
-C     LDB2    INTEGER
-C             The leading dimension of array B2.  LDB2 >= MAX(1,N2).
-C
-C     C2      (input) DOUBLE PRECISION array, dimension (LDC2,N2)
-C             The leading P-by-N2 part of this array must contain the
-C             state/output matrix C2 for the second system.
-C
-C     LDC2    INTEGER
-C             The leading dimension of array C2.
-C             LDC2 >= MAX(1,P) if N2 > 0.
-C             LDC2 >= 1 if N2 = 0.
-C
-C     D2      (input) DOUBLE PRECISION array, dimension (LDD2,M)
-C             The leading P-by-M part of this array must contain the
-C             input/output matrix D2 for the second system.
-C
-C     LDD2    INTEGER
-C             The leading dimension of array D2.  LDD2 >= MAX(1,P).
-C
-C     N       (output) INTEGER
-C             The number of state variables (N1 + N2) in the resulting
-C             system, i.e. the order of the matrix A, the number of rows
-C             of B and the number of columns of C.
-C
-C     A       (output) DOUBLE PRECISION array, dimension (LDA,N1+N2)
-C             The leading N-by-N part of this array contains the state
-C             transition matrix A for the resulting system.
-C             The array A can overlap A1 if OVER = 'O'.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N1+N2).
-C
-C     B       (output) DOUBLE PRECISION array, dimension (LDB,M)
-C             The leading N-by-M part of this array contains the
-C             input/state matrix B for the resulting system.
-C             The array B can overlap B1 if OVER = 'O'.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N1+N2).
-C
-C     C       (output) DOUBLE PRECISION array, dimension (LDC,N1+N2)
-C             The leading P-by-N part of this array contains the
-C             state/output matrix C for the resulting system.
-C             The array C can overlap C1 if OVER = 'O'.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.
-C             LDC >= MAX(1,P) if N1+N2 > 0.
-C             LDC >= 1 if N1+N2 = 0.
-C
-C     D       (output) DOUBLE PRECISION array, dimension (LDD,M)
-C             The leading P-by-M part of this array contains the
-C             input/output matrix D for the resulting system.
-C             The array D can overlap D1 if OVER = 'O'.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-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     METHOD
-C
-C     The matrices of the resulting systems are determined as:
-C
-C           ( A1   0  )             ( B1 )
-C       A = (         ) ,       B = (    ) ,
-C           ( 0    A2 )             ( B2 )
-C
-C       C = ( C1  alpha*C2 ) ,  D = D1 + alpha*D2 .
-C
-C     REFERENCES
-C
-C     None
-C
-C     NUMERICAL ASPECTS
-C
-C     None
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Research Establishment,
-C     Oberpfaffenhofen, Germany, and V. Sima, Katholieke Univ. Leuven,
-C     Belgium, Nov. 1996.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, July 2003,
-C     Feb. 2004.
-C
-C     KEYWORDS
-C
-C     Multivariable system, state-space model, state-space
-C     representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO=0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         OVER
-      INTEGER           INFO, LDA, LDA1, LDA2, LDB, LDB1, LDB2, LDC,
-     $                  LDC1, LDC2, LDD, LDD1, LDD2, M, N, N1, N2, P
-      DOUBLE PRECISION  ALPHA
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), A1(LDA1,*), A2(LDA2,*), B(LDB,*),
-     $                  B1(LDB1,*), B2(LDB2,*), C(LDC,*), C1(LDC1,*),
-     $                  C2(LDC2,*), D(LDD,*), D1(LDD1,*), D2(LDD2,*)
-C     .. Local Scalars ..
-      LOGICAL           LOVER
-      INTEGER           I, J, N1P1
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DLACPY, DLASCL, DLASET, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX, MIN
-C     .. Executable Statements ..
-C
-      LOVER = LSAME( OVER, 'O' )
-      N = N1 + N2
-      INFO = 0
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.LOVER .AND. .NOT.LSAME( OVER, 'N' ) ) THEN
-         INFO = -1
-      ELSE IF( N1.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( N2.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( LDA1.LT.MAX( 1, N1 ) ) THEN
-         INFO = -8
-      ELSE IF( LDB1.LT.MAX( 1, N1 ) ) THEN
-         INFO = -10
-      ELSE IF( ( N1.GT.0 .AND. LDC1.LT.MAX( 1, P ) ) .OR.
-     $         ( N1.EQ.0 .AND. LDC1.LT.1 ) ) THEN
-         INFO = -12
-      ELSE IF( LDD1.LT.MAX( 1, P ) ) THEN
-         INFO = -14
-      ELSE IF( LDA2.LT.MAX( 1, N2 ) ) THEN
-         INFO = -16
-      ELSE IF( LDB2.LT.MAX( 1, N2 ) ) THEN
-         INFO = -18
-      ELSE IF( ( N2.GT.0 .AND. LDC2.LT.MAX( 1, P ) ) .OR.
-     $         ( N2.EQ.0 .AND. LDC2.LT.1 ) ) THEN
-         INFO = -20
-      ELSE IF( LDD2.LT.MAX( 1, P ) ) THEN
-         INFO = -22
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -25
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -27
-      ELSE IF( ( N.GT.0 .AND. LDC.LT.MAX( 1, P ) ) .OR.
-     $         ( N.EQ.0 .AND. LDC.LT.1 ) ) THEN
-         INFO = -29
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -31
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB05PD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( MAX( N, MIN( M, P ) ).EQ.0 )
-     $   RETURN
-C
-      N1P1 = N1 + 1
-C
-C                       ( A1   0  )
-C     Construct     A = (         ) .
-C                       ( 0    A2 )
-C
-      IF ( LOVER .AND. LDA1.LE.LDA ) THEN
-         IF ( LDA1.LT.LDA ) THEN
-C
-            DO 20 J = N1, 1, -1
-               DO 10 I = N1, 1, -1
-                  A(I,J) = A1(I,J)
-   10          CONTINUE
-   20       CONTINUE
-C
-         END IF
-      ELSE
-         CALL DLACPY( 'F', N1, N1, A1, LDA1, A, LDA )
-      END IF
-C
-      IF ( N2.GT.0 ) THEN
-         CALL DLASET( 'F', N1, N2, ZERO, ZERO, A(1,N1P1), LDA )
-         CALL DLASET( 'F', N2, N1, ZERO, ZERO, A(N1P1,1), LDA )
-         CALL DLACPY( 'F', N2, N2, A2, LDA2, A(N1P1,N1P1), LDA )
-      END IF
-C
-C                        ( B1 )
-C     Construct      B = (    ) .
-C                        ( B2 )
-C
-      IF ( LOVER .AND. LDB1.LE.LDB ) THEN
-         IF ( LDB1.LT.LDB ) THEN
-C
-            DO 40 J = M, 1, -1
-               DO 30 I = N1, 1, -1
-                  B(I,J) = B1(I,J)
-   30          CONTINUE
-   40       CONTINUE
-C
-         END IF
-      ELSE
-         CALL DLACPY( 'F', N1, M, B1, LDB1, B, LDB )
-      END IF
-C
-      IF ( N2.GT.0 )
-     $   CALL DLACPY( 'F', N2, M, B2, LDB2, B(N1P1,1), LDB )
-C
-C     Construct      C = ( C1 alpha*C2 ) .
-C
-      IF ( LOVER .AND. LDC1.LE.LDC ) THEN
-         IF ( LDC1.LT.LDC ) THEN
-C
-            DO 60 J = N1, 1, -1
-               DO 50 I = P, 1, -1
-                  C(I,J) = C1(I,J)
-   50          CONTINUE
-   60       CONTINUE
-C
-         END IF
-      ELSE
-         CALL DLACPY( 'F', P, N1, C1, LDC1, C, LDC )
-      END IF
-C
-      IF ( N2.GT.0 ) THEN
-         CALL DLACPY( 'F', P, N2, C2, LDC2, C(1,N1P1), LDC )
-         IF ( ALPHA.NE.ONE )
-     $      CALL DLASCL( 'G', 0, 0, ONE, ALPHA, P, N2, C(1,N1P1), LDC,
-     $                   INFO )
-      END IF
-C
-C     Construct       D = D1 + alpha*D2 .
-C
-      IF ( LOVER .AND. LDD1.LE.LDD ) THEN
-         IF ( LDD1.LT.LDD ) THEN
-C
-            DO 80 J = M, 1, -1
-               DO 70 I = P, 1, -1
-                  D(I,J) = D1(I,J)
-   70          CONTINUE
-   80       CONTINUE
-C
-         END IF
-      ELSE
-         CALL DLACPY( 'F', P, M, D1, LDD1, D, LDD )
-      END IF
-C
-      DO 90 J = 1, M
-         CALL DAXPY( P, ALPHA, D2(1,J), 1, D(1,J), 1 )
-   90 CONTINUE
-C
-      RETURN
-C *** Last line of AB05PD ***
-      END
--- a/extra/control-devel/src/AB05QD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,419 +0,0 @@
-      SUBROUTINE AB05QD( OVER, N1, M1, P1, N2, M2, P2, A1, LDA1, B1,
-     $                   LDB1, C1, LDC1, D1, LDD1, A2, LDA2, B2, LDB2,
-     $                   C2, LDC2, D2, LDD2, N, M, P, A, LDA, B, LDB,
-     $                   C, LDC, D, LDD, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To append two systems G1 and G2 in state-space form together.
-C     If G1 = (A1,B1,C1,D1) and G2 = (A2,B2,C2,D2) are the state-space
-C     models of the given two systems having the transfer-function
-C     matrices G1 and G2, respectively, this subroutine constructs the
-C     state-space model G = (A,B,C,D) which corresponds to the
-C     transfer-function matrix
-C
-C                           ( G1 0  )
-C                       G = (       )
-C                           ( 0  G2 )
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     OVER    CHARACTER*1
-C             Indicates whether the user wishes to overlap pairs of
-C             arrays, as follows:
-C             = 'N':  Do not overlap;
-C             = 'O':  Overlap pairs of arrays: A1 and A, B1 and B,
-C                     C1 and C, and D1 and D, i.e. the same name is
-C                     effectively used for each pair (for all pairs)
-C                     in the routine call.  In this case, setting
-C                     LDA1 = LDA, LDB1 = LDB, LDC1 = LDC, and LDD1 = LDD
-C                     will give maximum efficiency.
-C
-C     Input/Output Parameters
-C
-C     N1      (input) INTEGER
-C             The number of state variables in the first system, i.e.
-C             the order of the matrix A1, the number of rows of B1 and
-C             the number of columns of C1.  N1 >= 0.
-C
-C     M1      (input) INTEGER
-C             The number of input variables in the first system, i.e.
-C             the number of columns of matrices B1 and D1.  M1 >= 0.
-C
-C     P1      (input) INTEGER
-C             The number of output variables in the first system, i.e.
-C             the number of rows of matrices C1 and D1.  P1 >= 0.
-C
-C     N2      (input) INTEGER
-C             The number of state variables in the second system, i.e.
-C             the order of the matrix A2, the number of rows of B2 and
-C             the number of columns of C2.  N2 >= 0.
-C
-C     M2      (input) INTEGER
-C             The number of input variables in the second system, i.e.
-C             the number of columns of matrices B2 and D2.  M2 >= 0.
-C
-C     P2      (input) INTEGER
-C             The number of output variables in the second system, i.e.
-C             the number of rows of matrices C2 and D2.  P2 >= 0.
-C
-C     A1      (input) DOUBLE PRECISION array, dimension (LDA1,N1)
-C             The leading N1-by-N1 part of this array must contain the
-C             state transition matrix A1 for the first system.
-C
-C     LDA1    INTEGER
-C             The leading dimension of array A1.  LDA1 >= MAX(1,N1).
-C
-C     B1      (input) DOUBLE PRECISION array, dimension (LDB1,M1)
-C             The leading N1-by-M1 part of this array must contain the
-C             input/state matrix B1 for the first system.
-C
-C     LDB1    INTEGER
-C             The leading dimension of array B1.  LDB1 >= MAX(1,N1).
-C
-C     C1      (input) DOUBLE PRECISION array, dimension (LDC1,N1)
-C             The leading P1-by-N1 part of this array must contain the
-C             state/output matrix C1 for the first system.
-C
-C     LDC1    INTEGER
-C             The leading dimension of array C1.
-C             LDC1 >= MAX(1,P1) if N1 > 0.
-C             LDC1 >= 1 if N1 = 0.
-C
-C     D1      (input) DOUBLE PRECISION array, dimension (LDD1,M1)
-C             The leading P1-by-M1 part of this array must contain the
-C             input/output matrix D1 for the first system.
-C
-C     LDD1    INTEGER
-C             The leading dimension of array D1.  LDD1 >= MAX(1,P1).
-C
-C     A2      (input) DOUBLE PRECISION array, dimension (LDA2,N2)
-C             The leading N2-by-N2 part of this array must contain the
-C             state transition matrix A2 for the second system.
-C
-C     LDA2    INTEGER
-C             The leading dimension of array A2.  LDA2 >= MAX(1,N2).
-C
-C     B2      (input) DOUBLE PRECISION array, dimension (LDB2,M2)
-C             The leading N2-by-M2 part of this array must contain the
-C             input/state matrix B2 for the second system.
-C
-C     LDB2    INTEGER
-C             The leading dimension of array B2.  LDB2 >= MAX(1,N2).
-C
-C     C2      (input) DOUBLE PRECISION array, dimension (LDC2,N2)
-C             The leading P2-by-N2 part of this array must contain the
-C             state/output matrix C2 for the second system.
-C
-C     LDC2    INTEGER
-C             The leading dimension of array C2.
-C             LDC2 >= MAX(1,P2) if N2 > 0.
-C             LDC2 >= 1 if N2 = 0.
-C
-C     D2      (input) DOUBLE PRECISION array, dimension (LDD2,M2)
-C             The leading P2-by-M2 part of this array must contain the
-C             input/output matrix D2 for the second system.
-C
-C     LDD2    INTEGER
-C             The leading dimension of array D2.  LDD2 >= MAX(1,P2).
-C
-C     N       (output) INTEGER
-C             The number of state variables (N1 + N2) in the resulting
-C             system, i.e. the order of the matrix A, the number of rows
-C             of B and the number of columns of C.
-C
-C     M       (output) INTEGER
-C             The number of input variables (M1 + M2) in the resulting
-C             system, i.e. the number of columns of B and D.
-C
-C     P       (output) INTEGER
-C             The number of output variables (P1 + P2) of the resulting
-C             system, i.e. the number of rows of C and D.
-C
-C     A       (output) DOUBLE PRECISION array, dimension (LDA,N1+N2)
-C             The leading N-by-N part of this array contains the state
-C             transition matrix A for the resulting system.
-C             The array A can overlap A1 if OVER = 'O'.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N1+N2).
-C
-C     B       (output) DOUBLE PRECISION array, dimension (LDB,M1+M2)
-C             The leading N-by-M part of this array contains the
-C             input/state matrix B for the resulting system.
-C             The array B can overlap B1 if OVER = 'O'.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N1+N2).
-C
-C     C       (output) DOUBLE PRECISION array, dimension (LDC,N1+N2)
-C             The leading P-by-N part of this array contains the
-C             state/output matrix C for the resulting system.
-C             The array C can overlap C1 if OVER = 'O'.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.
-C             LDC >= MAX(1,P1+P2) if N1+N2 > 0.
-C             LDC >= 1 if N1+N2 = 0.
-C
-C     D       (output) DOUBLE PRECISION array, dimension (LDD,M1+M2)
-C             The leading P-by-M part of this array contains the
-C             input/output matrix D for the resulting system.
-C             The array D can overlap D1 if OVER = 'O'.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P1+P2).
-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     METHOD
-C
-C     The matrices of the resulting systems are determined as:
-C
-C           ( A1   0  )         ( B1  0  )
-C       A = (         ) ,   B = (        ) ,
-C           ( 0    A2 )         ( 0   B2 )
-C
-C           ( C1   0  )         ( D1  0  )
-C       C = (         ) ,   D = (        ) .
-C           ( 0    C2 )         ( 0   D2 )
-C
-C     REFERENCES
-C
-C     None
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Research Establishment,
-C     Oberpfaffenhofen, Germany, and V. Sima, Katholieke Univ. Leuven,
-C     Belgium, Nov. 1996.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Feb. 2004.
-C
-C     KEYWORDS
-C
-C     Multivariable system, state-space model, state-space
-C     representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO
-      PARAMETER         ( ZERO=0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         OVER
-      INTEGER           INFO, LDA, LDA1, LDA2, LDB, LDB1, LDB2, LDC,
-     $                  LDC1, LDC2, LDD, LDD1, LDD2, M, M1, M2, N, N1,
-     $                  N2, P, P1, P2
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), A1(LDA1,*), A2(LDA2,*), B(LDB,*),
-     $                  B1(LDB1,*), B2(LDB2,*), C(LDC,*), C1(LDC1,*),
-     $                  C2(LDC2,*), D(LDD,*), D1(LDD1,*), D2(LDD2,*)
-C     .. Local Scalars ..
-      LOGICAL           LOVER
-      INTEGER           I, J
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DLACPY, DLASET, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX, MIN
-C     .. Executable Statements ..
-C
-      LOVER = LSAME( OVER, 'O' )
-      N = N1 + N2
-      M = M1 + M2
-      P = P1 + P2
-      INFO = 0
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.LOVER .AND. .NOT.LSAME( OVER, 'N' ) ) THEN
-         INFO = -1
-      ELSE IF( N1.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M1.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P1.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( N2.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M2.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( P2.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( LDA1.LT.MAX( 1, N1 ) ) THEN
-         INFO = -9
-      ELSE IF( LDB1.LT.MAX( 1, N1 ) ) THEN
-         INFO = -11
-      ELSE IF( ( N1.GT.0 .AND. LDC1.LT.MAX( 1, P1 ) ) .OR.
-     $         ( N1.EQ.0 .AND. LDC1.LT.1 ) ) THEN
-         INFO = -13
-      ELSE IF( LDD1.LT.MAX( 1, P1 ) ) THEN
-         INFO = -15
-      ELSE IF( LDA2.LT.MAX( 1, N2 ) ) THEN
-         INFO = -17
-      ELSE IF( LDB2.LT.MAX( 1, N2 ) ) THEN
-         INFO = -19
-      ELSE IF( ( N2.GT.0 .AND. LDC2.LT.MAX( 1, P2 ) ) .OR.
-     $         ( N2.EQ.0 .AND. LDC2.LT.1 ) ) THEN
-         INFO = -21
-      ELSE IF( LDD2.LT.MAX( 1, P2 ) ) THEN
-         INFO = -23
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -28
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -30
-      ELSE IF( ( N.GT.0 .AND. LDC.LT.MAX( 1, P ) ) .OR.
-     $         ( N.EQ.0 .AND. LDC.LT.1 ) ) THEN
-         INFO = -32
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -34
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB05QD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( MAX( N, MIN( M, P ) ).EQ.0 )
-     $   RETURN
-C                       ( A1   0  )
-C     Construct     A = (         ) .
-C                       ( 0    A2 )
-C
-      IF ( LOVER .AND. LDA1.LE.LDA ) THEN
-         IF ( LDA1.LT.LDA ) THEN
-C
-            DO 20 J = N1, 1, -1
-               DO 10 I = N1, 1, -1
-                  A(I,J) = A1(I,J)
-   10          CONTINUE
-   20       CONTINUE
-C
-         END IF
-      ELSE
-         CALL DLACPY( 'F', N1, N1, A1, LDA1, A, LDA )
-      END IF
-C
-      IF ( N2.GT.0 ) THEN
-         CALL DLASET( 'F', N1, N2, ZERO, ZERO, A(1,N1+1), LDA )
-         CALL DLASET( 'F', N2, N1, ZERO, ZERO, A(N1+1,1), LDA )
-         CALL DLACPY( 'F', N2, N2, A2, LDA2, A(N1+1,N1+1), LDA )
-      END IF
-C
-C                        ( B1  0  )
-C     Construct      B = (        ) .
-C                        ( 0   B2 )
-C
-      IF ( LOVER .AND. LDB1.LE.LDB ) THEN
-         IF ( LDB1.LT.LDB ) THEN
-C
-            DO 40 J = M1, 1, -1
-               DO 30 I = N1, 1, -1
-                  B(I,J) = B1(I,J)
-   30          CONTINUE
-   40       CONTINUE
-C
-         END IF
-      ELSE
-         CALL DLACPY( 'F', N1, M1, B1, LDB1, B, LDB )
-      END IF
-C
-      IF ( M2.GT.0 )
-     $   CALL DLASET( 'F', N1, M2, ZERO, ZERO, B(1,M1+1), LDB )
-      IF ( N2.GT.0 ) THEN
-         CALL DLASET( 'F', N2, M1, ZERO, ZERO, B(N1+1,1), LDB )
-         IF ( M2.GT.0 )
-     $      CALL DLACPY( 'F', N2, M2, B2, LDB2, B(N1+1,M1+1), LDB )
-      END IF
-C
-C                         ( C1   0  )
-C     Construct      C =  (         ) .
-C                         ( 0    C2 )
-C
-      IF ( LOVER .AND. LDC1.LE.LDC ) THEN
-         IF ( LDC1.LT.LDC ) THEN
-C
-            DO 60 J = N1, 1, -1
-               DO 50 I = P1, 1, -1
-                  C(I,J) = C1(I,J)
-   50          CONTINUE
-   60       CONTINUE
-C
-         END IF
-      ELSE
-         CALL DLACPY( 'F', P1, N1, C1, LDC1, C, LDC )
-      END IF
-C
-      IF ( N2.GT.0 )
-     $   CALL DLASET( 'F', P1, N2, ZERO, ZERO, C(1,N1+1), LDC )
-      IF ( P2.GT.0 ) THEN
-         IF ( N1.GT.0 )
-     $      CALL DLASET( 'F', P2, N1, ZERO, ZERO, C(P1+1,1), LDC )
-         IF ( N2.GT.0 )
-     $      CALL DLACPY( 'F', P2, N2, C2, LDC2, C(P1+1,N1+1), LDC )
-      END IF
-C
-C                          ( D1  0  )
-C     Construct       D =  (        ) .
-C                          ( 0   D2 )
-C
-      IF ( LOVER .AND. LDD1.LE.LDD ) THEN
-         IF ( LDD1.LT.LDD ) THEN
-C
-            DO 80 J = M1, 1, -1
-               DO 70 I = P1, 1, -1
-                  D(I,J) = D1(I,J)
-   70          CONTINUE
-   80       CONTINUE
-C
-         END IF
-      ELSE
-         CALL DLACPY( 'F', P1, M1, D1, LDD1, D, LDD )
-      END IF
-C
-      IF ( M2.GT.0 )
-     $   CALL DLASET( 'F', P1, M2, ZERO, ZERO, D(1,M1+1), LDD )
-      IF ( P2.GT.0 ) THEN
-         CALL DLASET( 'F', P2, M1, ZERO, ZERO, D(P1+1,1), LDD )
-         IF ( M2.GT.0 )
-     $      CALL DLACPY( 'F', P2, M2, D2, LDD2, D(P1+1,M1+1), LDD )
-      END IF
-C
-      RETURN
-C *** Last line of AB05QD ***
-      END
--- a/extra/control-devel/src/AB07MD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,224 +0,0 @@
-      SUBROUTINE AB07MD( JOBD, N, M, P, A, LDA, B, LDB, C, LDC, D, LDD,
-     $                   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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To find the dual of a given state-space representation.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBD    CHARACTER*1
-C             Specifies whether or not a non-zero matrix D appears in
-C             the given state space model:
-C             = 'D':  D is present;
-C             = 'Z':  D is assumed a zero matrix.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the state-space representation.  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     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the original state dynamics matrix A.
-C             On exit, the leading N-by-N part of this array contains
-C             the dual state dynamics matrix A'.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension
-C             (LDB,MAX(M,P))
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, the leading N-by-P part of this array contains
-C             the dual input/state matrix C'.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, the leading M-by-N part of this array contains
-C             the dual state/output matrix B'.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.
-C             LDC >= MAX(1,M,P) if N > 0.
-C             LDC >= 1 if N = 0.
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension
-C             (LDD,MAX(M,P))
-C             On entry, if JOBD = 'D', the leading P-by-M part of this
-C             array must contain the original direct transmission
-C             matrix D.
-C             On exit, if JOBD = 'D', the leading M-by-P part of this
-C             array contains the dual direct transmission matrix D'.
-C             The array D is not referenced if JOBD = 'Z'.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.
-C             LDD >= MAX(1,M,P) if JOBD = 'D'.
-C             LDD >= 1 if JOBD = 'Z'.
-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     METHOD
-C
-C     If the given state-space representation is the M-input/P-output
-C     (A,B,C,D), its dual is simply the P-input/M-output (A',C',B',D').
-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, Dec. 1996.
-C     Supersedes Release 2.0 routine AB07AD by T.W.C.Williams, Kingston
-C     Polytechnic, United Kingdom, March 1982.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Feb. 2004.
-C
-C     KEYWORDS
-C
-C     Dual system, state-space model, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Scalar Arguments ..
-      CHARACTER         JOBD
-      INTEGER           INFO, LDA, LDB, LDC, LDD, M, N, P
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*)
-C     .. Local Scalars ..
-      LOGICAL           LJOBD
-      INTEGER           J, MINMP, MPLIM
-C     .. External functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External subroutines ..
-      EXTERNAL          DCOPY, DSWAP, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX, MIN
-C     .. Executable Statements ..
-C
-      INFO = 0
-      LJOBD = LSAME( JOBD, 'D' )
-      MPLIM = MAX( M, P )
-      MINMP = MIN( M, P )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.LJOBD .AND. .NOT.LSAME( JOBD, 'Z' )  ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( ( N.GT.0 .AND. LDC.LT.MAX( 1, MPLIM ) ) .OR.
-     $         ( N.EQ.0 .AND. LDC.LT.1 ) ) THEN
-         INFO = -10
-      ELSE IF( ( LJOBD .AND. LDD.LT.MAX( 1, MPLIM ) ) .OR.
-     $    ( .NOT.LJOBD .AND. LDD.LT.1 ) ) THEN
-         INFO = -12
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB07MD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( MAX( N, MINMP ).EQ.0 )
-     $   RETURN
-C
-      IF ( N.GT.0 ) THEN
-C
-C        Transpose A, if non-scalar.
-C
-         DO 10 J = 1, N - 1
-            CALL DSWAP( N-J, A(J+1,J), 1, A(J,J+1), LDA )
-   10    CONTINUE
-C
-C        Replace B by C' and C by B'.
-C
-         DO 20 J = 1, MPLIM
-            IF ( J.LE.MINMP ) THEN
-               CALL DSWAP( N, B(1,J), 1, C(J,1), LDC )
-            ELSE IF ( J.GT.P ) THEN
-               CALL DCOPY( N, B(1,J), 1, C(J,1), LDC )
-            ELSE
-               CALL DCOPY( N, C(J,1), LDC, B(1,J), 1 )
-            END IF
-   20    CONTINUE
-C
-      END IF
-C
-      IF ( LJOBD .AND. MINMP.GT.0 ) THEN
-C
-C        Transpose D, if non-scalar.
-C
-         DO 30 J = 1, MPLIM
-            IF ( J.LT.MINMP ) THEN
-               CALL DSWAP( MINMP-J, D(J+1,J), 1, D(J,J+1), LDD )
-            ELSE IF ( J.GT.P ) THEN
-               CALL DCOPY( P, D(1,J), 1, D(J,1), LDD )
-            ELSE IF ( J.GT.M ) THEN
-               CALL DCOPY( M, D(J,1), LDD, D(1,J), 1 )
-            END IF
-   30    CONTINUE
-C
-      END IF
-C
-      RETURN
-C *** Last line of AB07MD ***
-      END
--- a/extra/control-devel/src/AB07ND.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,303 +0,0 @@
-      SUBROUTINE AB07ND( N, M, A, LDA, B, LDB, C, LDC, D, LDD, RCOND,
-     $                   IWORK, DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the inverse (Ai,Bi,Ci,Di) of a given system (A,B,C,D).
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the state matrix A.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs and outputs.  M >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state matrix A of the original system.
-C             On exit, the leading N-by-N part of this array contains
-C             the state matrix Ai of the inverse system.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input matrix B of the original system.
-C             On exit, the leading N-by-M part of this array contains
-C             the input matrix Bi of the inverse system.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading M-by-N part of this array must
-C             contain the output matrix C of the original system.
-C             On exit, the leading M-by-N part of this array contains
-C             the output matrix Ci of the inverse system.
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.  LDC >= MAX(1,M).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading M-by-M part of this array must
-C             contain the feedthrough matrix D of the original system.
-C             On exit, the leading M-by-M part of this array contains
-C             the feedthrough matrix Di of the inverse system.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.  LDD >= MAX(1,M).
-C
-C     RCOND   (output) DOUBLE PRECISION
-C             The estimated reciprocal condition number of the
-C             feedthrough matrix D of the original system.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (2*M)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0 or M+1, DWORK(1) returns the optimal
-C             value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.  LDWORK >= MAX(1,4*M).
-C             For good 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             = i:  the matrix D is exactly singular; the (i,i) diagonal
-C                   element is zero, i <= M; RCOND was set to zero;
-C             = M+1:  the matrix D is numerically singular, i.e., RCOND
-C                   is less than the relative machine precision, EPS
-C                   (see LAPACK Library routine DLAMCH). The
-C                   calculations have been completed, but the results
-C                   could be very inaccurate.
-C
-C     METHOD
-C
-C     The matrices of the inverse system are computed with the formulas:
-C                   -1              -1         -1           -1
-C       Ai = A - B*D  *C,  Bi = -B*D  ,  Ci = D  *C,  Di = D  .
-C
-C     NUMERICAL ASPECTS
-C
-C     The accuracy depends mainly on the condition number of the matrix
-C     D to be inverted. The estimated reciprocal condition number is
-C     returned in RCOND.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, March 2000.
-C     D. Sima, University of Bucharest, April 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 2000.
-C     Based on the routine SYSINV, A. Varga, 1992.
-C
-C     REVISIONS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, July 2000.
-C
-C     KEYWORDS
-C
-C     Inverse system, state-space model, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   RCOND
-      INTEGER            INFO, LDA, LDB, LDC, LDD, LDWORK, M, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                   DWORK(*)
-      INTEGER            IWORK(*)
-C     .. Local Scalars ..
-      DOUBLE PRECISION   DNORM
-      INTEGER            BL, CHUNK, I, IERR, J, MAXWRK
-      LOGICAL            BLAS3, BLOCK
-C     .. External Functions ..
-      DOUBLE PRECISION   DLAMCH, DLANGE
-      INTEGER            ILAENV
-      EXTERNAL           DLAMCH, DLANGE, ILAENV
-C     .. External Subroutines ..
-      EXTERNAL           DCOPY, DGECON, DGEMM, DGEMV, DGETRF, DGETRI,
-     $                   DLACPY, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          DBLE, MAX, MIN
-C     .. Executable Statements ..
-C
-      INFO = 0
-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( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -4
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
-         INFO = -8
-      ELSE IF( LDD.LT.MAX( 1, M ) ) THEN
-         INFO = -10
-      ELSE IF( LDWORK.LT.MAX( 1, 4*M ) ) THEN
-         INFO = -14
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB07ND', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( M.EQ.0 ) THEN
-         RCOND    = ONE
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Factorize D.
-C
-      CALL DGETRF( M, M, D, LDD, IWORK, INFO )
-      IF ( INFO.NE.0 ) THEN
-         RCOND = ZERO
-         RETURN
-      END IF
-C
-C     Compute the reciprocal condition number of the matrix D.
-C     Workspace: need   4*M.
-C     (Note: Comments in the code beginning "Workspace:" describe the
-C      minimal amount of workspace needed at that point in the code,
-C      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
-      DNORM = DLANGE( '1-norm', M, M, D, LDD, DWORK )
-      CALL DGECON( '1-norm', M, D, LDD, DNORM, RCOND, DWORK, IWORK(M+1),
-     $             IERR )
-      IF ( RCOND.LT.DLAMCH( 'Epsilon' ) )
-     $   INFO = M + 1
-C                   -1
-C     Compute Di = D  .
-C     Workspace: need   M;
-C                prefer M*NB.
-C
-      MAXWRK = MAX( 4*M, M*ILAENV( 1, 'DGETRI', ' ', M, -1, -1, -1 ) )
-      CALL DGETRI( M, D, LDD, IWORK, DWORK, LDWORK, IERR )
-      IF ( N.GT.0 ) THEN
-         CHUNK = LDWORK / M
-         BLAS3 = CHUNK.GE.N .AND. M.GT.1
-         BLOCK = MIN( CHUNK, M ).GT.1
-C                          -1
-C        Compute  Bi = -B*D  .
-C
-         IF ( BLAS3 ) THEN
-C
-C           Enough workspace for a fast BLAS 3 algorithm.
-C
-            CALL DLACPY( 'Full', N, M, B, LDB, DWORK, N )
-            CALL DGEMM( 'NoTranspose', 'NoTranspose', N, M, M, -ONE,
-     $                  DWORK, N, D, LDD, ZERO, B, LDB )
-C
-         ELSE IF( BLOCK ) THEN
-C
-C           Use as many rows of B as possible.
-C
-            DO 10 I = 1, N, CHUNK
-               BL = MIN( N-I+1, CHUNK )
-               CALL DLACPY( 'Full', BL, M, B(I,1), LDB, DWORK, BL )
-               CALL DGEMM( 'NoTranspose', 'NoTranspose', BL, M, M, -ONE,
-     $                     DWORK, BL, D, LDD, ZERO, B(I,1), LDB )
-   10       CONTINUE
-C
-         ELSE
-C
-C           Use a BLAS 2 algorithm.
-C
-            DO 20 I = 1, N
-               CALL DCOPY( M, B(I,1), LDB, DWORK, 1 )
-               CALL DGEMV( 'Transpose', M, M, -ONE, D, LDD, DWORK, 1,
-     $                     ZERO, B(I,1), LDB )
-   20       CONTINUE
-C
-         END IF
-C
-C        Compute  Ai = A + Bi*C.
-C
-         CALL DGEMM( 'NoTranspose', 'NoTranspose', N, N, M, ONE, B, LDB,
-     $               C, LDC, ONE, A, LDA )
-C                        -1
-C        Compute  C <-- D  *C.
-C
-         IF ( BLAS3 ) THEN
-C
-C           Enough workspace for a fast BLAS 3 algorithm.
-C
-            CALL DLACPY( 'Full', M, N, C, LDC, DWORK, M )
-            CALL DGEMM( 'NoTranspose', 'NoTranspose', M, N, M, ONE,
-     $                  D, LDD, DWORK, M, ZERO, C, LDC )
-C
-         ELSE IF( BLOCK ) THEN
-C
-C           Use as many columns of C as possible.
-C
-            DO 30 J = 1, N, CHUNK
-               BL = MIN( N-J+1, CHUNK )
-               CALL DLACPY( 'Full', M, BL, C(1,J), LDC, DWORK, M )
-               CALL DGEMM( 'NoTranspose', 'NoTranspose', M, BL, M, ONE,
-     $                     D, LDD, DWORK, M, ZERO, C(1,J), LDC )
-   30       CONTINUE
-C
-         ELSE
-C
-C           Use a BLAS 2 algorithm.
-C
-            DO 40 J = 1, N
-               CALL DCOPY( M, C(1,J), 1, DWORK, 1 )
-               CALL DGEMV( 'NoTranspose', M, M, ONE, D, LDD, DWORK, 1,
-     $                     ZERO, C(1,J), 1 )
-   40       CONTINUE
-C
-         END IF
-      END IF
-C
-C     Return optimal workspace in DWORK(1).
-C
-      DWORK(1) = DBLE( MAX( MAXWRK, N*M ) )
-      RETURN
-C
-C *** Last line of AB07ND ***
-      END
--- a/extra/control-devel/src/AB08MD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,299 +0,0 @@
-      SUBROUTINE AB08MD( EQUIL, N, M, P, A, LDA, B, LDB, C, LDC, D, LDD,
-     $                   RANK, TOL, IWORK, DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the normal rank of the transfer-function matrix of a
-C     state-space model (A,B,C,D).
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     EQUIL   CHARACTER*1
-C             Specifies whether the user wishes to balance the compound
-C             matrix (see METHOD) as follows:
-C             = 'S':  Perform balancing (scaling);
-C             = 'N':  Do not perform balancing.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The number of state variables, i.e., the order of the
-C             matrix A.  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     A       (input) DOUBLE PRECISION array, dimension (LDA,N)
-C             The leading N-by-N part of this array must contain the
-C             state dynamics 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,M)
-C             The leading N-by-M part of this array must contain the
-C             input/state matrix B of the system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input) DOUBLE PRECISION array, dimension (LDC,N)
-C             The leading P-by-N part of this array must contain the
-C             state/output matrix C of the system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input) DOUBLE PRECISION array, dimension (LDD,M)
-C             The leading P-by-M part of this array must contain the
-C             direct transmission matrix D of the system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     RANK    (output) INTEGER
-C             The normal rank of the transfer-function matrix.
-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             If the user sets TOL to be less than SQRT((N+P)*(N+M))*EPS
-C             then the tolerance is taken as SQRT((N+P)*(N+M))*EPS,
-C             where EPS is the machine precision (see LAPACK Library
-C             Routine DLAMCH).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (2*N+MAX(M,P)+1)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= (N+P)*(N+M) +
-C                       MAX( MIN(P,M) + MAX(3*M-1,N), 1,
-C                            MIN(P,N) + MAX(3*P-1,N+P,N+M) )
-C             For optimum performance LDWORK should be larger.
-C
-C             If LDWORK = -1, then a workspace query is assumed;
-C             the routine only calculates the optimal size of the
-C             DWORK array, returns this value as the first entry of
-C             the DWORK array, and no error message related to LDWORK
-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     METHOD
-C
-C     The routine reduces the (N+P)-by-(M+N) compound matrix (B  A)
-C                                                            (D  C)
-C
-C     to one with the same invariant zeros and with D of full row rank.
-C     The normal rank of the transfer-function matrix is the rank of D.
-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 (see [2] and [1]).
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, May 2001.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, June 2001,
-C     Dec. 2003, Jan. 2009, Mar. 2009, Apr. 2009.
-C
-C     KEYWORDS
-C
-C     Multivariable system, orthogonal transformation,
-C     structural invariant.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         EQUIL
-      INTEGER           INFO, LDA, LDB, LDC, LDD, LDWORK, M, N, P, RANK
-      DOUBLE PRECISION  TOL
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*), DWORK(*)
-C     .. Local Scalars ..
-      LOGICAL           LEQUIL, LQUERY
-      INTEGER           I, KW, MU, NB, NINFZ, NKROL, NM, NP, NU, RO,
-     $                  SIGMA, WRKOPT
-      DOUBLE PRECISION  MAXRED, SVLMAX, THRESH, TOLER
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH, DLANGE
-      EXTERNAL          DLAMCH, DLANGE, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB08NX, DLACPY, TB01ID, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, INT, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      NP = N + P
-      NM = N + M
-      INFO = 0
-      LEQUIL = LSAME( EQUIL, 'S' )
-      LQUERY = ( LDWORK.EQ.-1 )
-      WRKOPT = NP*NM
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.LEQUIL .AND. .NOT.LSAME( EQUIL, 'N' ) ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -10
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -12
-      ELSE
-         KW = WRKOPT + MAX( MIN( P, M ) + MAX( 3*M-1, N ), 1,
-     $                      MIN( P, N ) + MAX( 3*P-1, NP, NM ) )
-         IF( LQUERY ) THEN
-            SVLMAX = ZERO
-            NINFZ  = 0
-            CALL AB08NX( N, M, P, P, 0, SVLMAX, DWORK, MAX( 1, NP ),
-     $                   NINFZ, IWORK, IWORK, MU, NU, NKROL, TOL, IWORK,
-     $                   DWORK, -1, INFO )
-            WRKOPT = MAX( KW, WRKOPT + INT( DWORK(1) ) )
-         ELSE IF( LDWORK.LT.KW ) THEN
-            INFO = -17
-         END IF
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB08MD', -INFO )
-         RETURN
-      ELSE IF( LQUERY ) THEN
-         DWORK(1) = WRKOPT
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( MIN( M, P ).EQ.0 ) THEN
-         RANK = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      DO 10 I = 1, 2*N+1
-         IWORK(I) = 0
-   10 CONTINUE
-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
-C     Construct the compound matrix  ( B  A ), dimension (N+P)-by-(M+N).
-C                                    ( D  C )
-C     Workspace: need   (N+P)*(N+M).
-C
-      CALL DLACPY( 'Full', N, M, B, LDB, DWORK, NP )
-      CALL DLACPY( 'Full', P, M, D, LDD, DWORK(N+1), NP )
-      CALL DLACPY( 'Full', N, N, A, LDA, DWORK(NP*M+1), NP )
-      CALL DLACPY( 'Full', P, N, C, LDC, DWORK(NP*M+N+1), NP )
-C
-C     If required, balance the compound matrix (default MAXRED).
-C     Workspace: need   N.
-C
-      KW = WRKOPT + 1
-      IF ( LEQUIL ) THEN
-         MAXRED = ZERO
-         CALL TB01ID( 'A', N, M, P, MAXRED, DWORK(NP*M+1), NP, DWORK,
-     $                NP, DWORK(NP*M+N+1), NP, DWORK(KW), INFO )
-         WRKOPT = WRKOPT + N
-      END IF
-C
-C     If required, set tolerance.
-C
-      THRESH = SQRT( DBLE( NP*NM ) )*DLAMCH( 'Precision' )
-      TOLER = TOL
-      IF ( TOLER.LT.THRESH ) TOLER = THRESH
-      SVLMAX = DLANGE( 'Frobenius', NP, NM, DWORK, NP, DWORK(KW) )
-C
-C     Reduce this system to one with the same invariant zeros and with
-C     D full row rank MU (the normal rank of the original system).
-C     Real workspace: need   (N+P)*(N+M) +
-C                            MAX( 1, MIN(P,M) + MAX(3*M-1,N),
-C                                    MIN(P,N) + MAX(3*P-1,N+P,N+M) );
-C                     prefer larger.
-C     Integer workspace: 2*N+MAX(M,P)+1.
-C
-      RO = P
-      SIGMA = 0
-      NINFZ = 0
-      CALL AB08NX( N, M, P, RO, SIGMA, SVLMAX, DWORK, NP, NINFZ, IWORK,
-     $             IWORK(N+1), MU, NU, NKROL, TOLER, IWORK(2*N+2),
-     $             DWORK(KW), LDWORK-KW+1, INFO )
-      RANK = MU
-C
-      DWORK(1) = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      RETURN
-C *** Last line of AB08MD ***
-      END
--- a/extra/control-devel/src/AB08NX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,446 +0,0 @@
-      SUBROUTINE AB08NX( N, M, P, RO, SIGMA, SVLMAX, ABCD, LDABCD,
-     $                   NINFZ, INFZ, KRONL, MU, NU, NKROL, TOL, IWORK,
-     $                   DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-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) DOUBLE PRECISION array, dimension
-C             (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 (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 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 LDWORK should be larger.
-C
-C             If LDWORK = -1, then a workspace query is assumed;
-C             the routine only calculates the optimal size of the
-C             DWORK array, returns this value as the first entry of
-C             the DWORK array, and no error message related to LDWORK
-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     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Nov. 1996.
-C     Supersedes Release 2.0 routine AB08BZ by F. Svaricek.
-C
-C     REVISIONS
-C
-C     V. Sima, Oct. 1997; Feb. 1998, Jan. 2009, Apr. 2009.
-C     A. Varga, May 1999; May 2001.
-C
-C     KEYWORDS
-C
-C     Generalized eigenvalue problem, Kronecker indices, multivariable
-C     system, orthogonal transformation, structural invariant.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO
-      PARAMETER         ( ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER           INFO, LDABCD, LDWORK, M, MU, N, NINFZ, NKROL,
-     $                  NU, P, RO, SIGMA
-      DOUBLE PRECISION  SVLMAX, TOL
-C     .. Array Arguments ..
-      INTEGER           INFZ(*), IWORK(*), KRONL(*)
-      DOUBLE PRECISION  ABCD(LDABCD,*), DWORK(*)
-C     .. Local Scalars ..
-      LOGICAL           LQUERY
-      INTEGER           I1, IK, IROW, ITAU, IZ, JWORK, MM1, MNTAU, MNU,
-     $                  MPM, NB, NP, RANK, RO1, TAU, WRKOPT
-      DOUBLE PRECISION  T
-C     .. Local Arrays ..
-      DOUBLE PRECISION  SVAL(3)
-C     .. External Functions ..
-      INTEGER           ILAENV
-      EXTERNAL          ILAENV
-C     .. External Subroutines ..
-      EXTERNAL          DLAPMT, DLARFG, DLASET, DLATZM, DORMQR, DORMRQ,
-     $                  MB03OY, MB03PY, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         INT, MAX, MIN
-C     .. Executable Statements ..
-C
-      NP   = N + P
-      MPM  = MIN( P, M )
-      INFO = 0
-      LQUERY = ( LDWORK.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.ZERO ) 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, 'DORMQR', 'LT', P, N, MPM,
-     $                               -1 ) )
-               WRKOPT = MAX( JWORK, MPM + MAX( 1, N )*NB )
-            ELSE
-               WRKOPT = JWORK
-            END IF
-            NB = MIN( 64, ILAENV( 1, 'DORMRQ', 'RT', NP, N, MIN( P, N ),
-     $                            -1 ) )
-            WRKOPT = MAX( WRKOPT, MIN( P, N ) + MAX( 1, NP )*NB )
-            NB = MIN( 64, ILAENV( 1, 'DORMRQ', 'LN', N, M+N,
-     $                            MIN( P, N ), -1 ) )
-            WRKOPT = MAX( WRKOPT, MIN( P, N ) + MAX( 1, M+N )*NB )
-         ELSE IF( LDWORK.LT.JWORK ) THEN
-            INFO = -18
-         END IF
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB08NX', -INFO )
-         RETURN
-      ELSE IF( LQUERY ) THEN
-         DWORK(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 "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
-      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           Workspace: need   M+N-1.
-C
-            DO 40 I1 = 1, SIGMA
-               CALL DLARFG( RO+1, ABCD(IROW,I1), ABCD(IROW+1,I1), 1, T )
-               CALL DLATZM( 'L', RO+1, MNU-I1, ABCD(IROW+1,I1), 1, T,
-     $                      ABCD(IROW,I1+1), ABCD(IROW+1,I1+1), LDABCD,
-     $                      DWORK )
-               IROW = IROW + 1
-   40       CONTINUE
-            CALL DLASET( '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        Integer workspace: need   M;
-C        Workspace: 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 MB03OY( RO1, M-SIGMA, ABCD(IROW,I1), LDABCD, TOL,
-     $                   SVLMAX, RANK, SVAL, IWORK, DWORK(ITAU),
-     $                   DWORK(JWORK), INFO )
-            WRKOPT = MAX( WRKOPT, JWORK + 3*M - 2 )
-C
-C           Apply the column permutations to matrices B and part of D.
-C
-            CALL DLAPMT( .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              Workspace: need   min(RO1,M) + NU;
-C                         prefer min(RO1,M) + NU*NB.
-C
-               CALL DORMQR( 'Left', 'Transpose', RO1, NU, RANK,
-     $                      ABCD(IROW,I1), LDABCD, DWORK(ITAU),
-     $                      ABCD(IROW,MM1), LDABCD, DWORK(JWORK),
-     $                      LDWORK-JWORK+1, INFO )
-               WRKOPT = MAX( WRKOPT, INT( DWORK(JWORK) ) + JWORK - 1 )
-               IF ( RO1.GT.1 )
-     $            CALL DLASET( '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        Integer Workspace: need TAU;
-C        Workspace: need min(TAU,NU) + 3*TAU - 1.
-C
-         CALL MB03PY( TAU, NU, ABCD(I1,MM1), LDABCD, TOL, SVLMAX, RANK,
-     $                SVAL, IWORK, DWORK(ITAU), DWORK(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           Workspace: need   min(TAU,NU) + NU + SIGMA; SIGMA <= P;
-C                      prefer min(TAU,NU) + (NU  + SIGMA)*NB.
-C
-            CALL DORMRQ( 'Right', 'Transpose', I1-1, NU, RANK,
-     $                   ABCD(IROW,MM1), LDABCD, DWORK(MNTAU-RANK+1),
-     $                   ABCD(1,MM1), LDABCD, DWORK(JWORK),
-     $                   LDWORK-JWORK+1, INFO )
-            WRKOPT = MAX( WRKOPT, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C           Apply Q to the first NU rows and M + NU columns of [ B  A ]
-C           from the left.
-C           Workspace: need   min(TAU,NU) + M + NU;
-C                      prefer min(TAU,NU) + (M + NU)*NB.
-C
-            CALL DORMRQ( 'Left', 'NoTranspose', NU, MNU, RANK,
-     $                   ABCD(IROW,MM1), LDABCD, DWORK(MNTAU-RANK+1),
-     $                   ABCD, LDABCD, DWORK(JWORK), LDWORK-JWORK+1,
-     $                   INFO )
-            WRKOPT = MAX( WRKOPT, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-            CALL DLASET( 'Full', RANK, NU-RANK, ZERO, ZERO,
-     $                   ABCD(IROW,MM1), LDABCD )
-            IF ( RANK.GT.1 )
-     $         CALL DLASET( '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
-      DWORK(1) = WRKOPT
-      RETURN
-C *** Last line of AB08NX ***
-      END
--- a/extra/control-devel/src/AB09AD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,363 +0,0 @@
-      SUBROUTINE AB09AD( DICO, JOB, EQUIL, ORDSEL, N, M, P, NR, A, LDA,
-     $                   B, LDB, C, LDC, HSV, TOL, IWORK, DWORK, LDWORK,
-     $                   IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order model (Ar,Br,Cr) for a stable original
-C     state-space representation (A,B,C) by using either the square-root
-C     or the balancing-free square-root Balance & Truncate (B & T)
-C     model reduction method.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     JOB     CHARACTER*1
-C             Specifies the model reduction approach to be used
-C             as follows:
-C             = 'B':  use the square-root Balance & Truncate method;
-C             = 'N':  use the balancing-free square-root
-C                     Balance & Truncate method.
-C
-C     EQUIL   CHARACTER*1
-C             Specifies whether the user wishes to preliminarily
-C             equilibrate the triplet (A,B,C) as follows:
-C             = 'S':  perform equilibration (scaling);
-C             = 'N':  do not perform equilibration.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting order NR is fixed;
-C             = 'A':  the resulting order NR is automatically determined
-C                     on basis of the given tolerance TOL.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation, i.e.
-C             the order of the matrix A.  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     NR      (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NR is the desired order of the
-C             resulting reduced order system.  0 <= NR <= N.
-C             On exit, if INFO = 0, NR is the order of the resulting
-C             reduced order model. NR is set as follows:
-C             if ORDSEL = 'F', NR is equal to MIN(NR,NMIN), where NR
-C             is the desired order on entry and NMIN is the order of a
-C             minimal realization of the given system; NMIN is
-C             determined as the number of Hankel singular values greater
-C             than N*EPS*HNORM(A,B,C), where EPS is the machine
-C             precision (see LAPACK Library Routine DLAMCH) and
-C             HNORM(A,B,C) is the Hankel norm of the system (computed
-C             in HSV(1));
-C             if ORDSEL = 'A', NR is equal to the number of Hankel
-C             singular values greater than MAX(TOL,N*EPS*HNORM(A,B,C)).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A.
-C             On exit, if INFO = 0, the leading NR-by-NR part of this
-C             array contains the state dynamics matrix Ar of the reduced
-C             order system.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, if INFO = 0, the leading NR-by-M part of this
-C             array contains the input/state matrix Br of the reduced
-C             order system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, if INFO = 0, the leading P-by-NR part of this
-C             array contains the state/output matrix Cr of the reduced
-C             order system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, it contains the Hankel singular values of
-C             the original system ordered decreasingly. HSV(1) is the
-C             Hankel norm of the system.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL contains the tolerance for
-C             determining the order of reduced system.
-C             For model reduction, the recommended value is
-C             TOL = c*HNORM(A,B,C), where c is a constant in the
-C             interval [0.00001,0.001], and HNORM(A,B,C) is the
-C             Hankel-norm of the given system (computed in HSV(1)).
-C             For computing a minimal realization, the recommended
-C             value is TOL = N*EPS*HNORM(A,B,C), where EPS is the
-C             machine precision (see LAPACK Library Routine DLAMCH).
-C             This value is used by default if TOL <= 0 on entry.
-C             If ORDSEL = 'F', the value of TOL is ignored.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK = 0, if JOB = 'B';
-C             LIWORK = N, if JOB = 'N'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1,N*(2*N+MAX(N,M,P)+5)+N*(N+1)/2).
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NR is greater
-C                   than the order of a minimal realization of the
-C                   given system. In this case, the resulting NR is
-C                   set automatically to a value corresponding to the
-C                   order of a minimal realization of the system.
-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 reduction of A to the real Schur form failed;
-C             = 2:  the state matrix A is not stable (if DICO = 'C')
-C                   or not convergent (if DICO = 'D');
-C             = 3:  the computation of Hankel singular values failed.
-C
-C     METHOD
-C
-C     Let be the stable linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t)                               (1)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system. The subroutine AB09AD determines for
-C     the given system (1), the matrices of a reduced order system
-C
-C          d[z(t)] = Ar*z(t) + Br*u(t)
-C          yr(t)   = Cr*z(t)                             (2)
-C
-C     such that
-C
-C           HSV(NR) <= INFNORM(G-Gr) <= 2*[HSV(NR+1) + ... + HSV(N)],
-C
-C     where G and Gr are transfer-function matrices of the systems
-C     (A,B,C) and (Ar,Br,Cr), respectively, and INFNORM(G) is the
-C     infinity-norm of G.
-C
-C     If JOB = 'B', the square-root Balance & Truncate method of [1]
-C     is used and, for DICO = 'C', the resulting model is balanced.
-C     By setting TOL <= 0, the routine can be used to compute balanced
-C     minimal state-space realizations of stable systems.
-C
-C     If JOB = 'N', the balancing-free square-root version of the
-C     Balance & Truncate method [2] is used.
-C     By setting TOL <= 0, the routine can be used to compute minimal
-C     state-space realizations of stable systems.
-C
-C     REFERENCES
-C
-C     [1] Tombs M.S. and Postlethwaite I.
-C         Truncated balanced realization of stable, non-minimal
-C         state-space systems.
-C         Int. J. Control, Vol. 46, pp. 1319-1330, 1987.
-C
-C     [2] Varga A.
-C         Efficient minimal realization procedure based on balancing.
-C         Proc. of IMACS/IFAC Symp. MCTS, Lille, France, May 1991,
-C         A. El Moudui, P. Borne, S. G. Tzafestas (Eds.),
-C         Vol. 2, pp. 42-46.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on accuracy enhancing square-root or
-C     balancing-free square-root techniques.
-C                                         3
-C     The algorithms require less than 30N  floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     C. Oara and A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, March 1998.
-C     Based on the RASP routines SRBT and SRBFT.
-C
-C     REVISIONS
-C
-C     May 2, 1998.
-C     November 11, 1998, V. Sima, Research Institute for Informatics,
-C     Bucharest.
-C
-C     KEYWORDS
-C
-C     Balancing, minimal state-space representation, model reduction,
-C     multivariable system, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, C100
-      PARAMETER         ( ONE = 1.0D0, C100 = 100.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, EQUIL, JOB, ORDSEL
-      INTEGER           INFO, IWARN, LDA, LDB, LDC, LDWORK, M, N, NR, P
-      DOUBLE PRECISION  TOL
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*), HSV(*)
-C     .. Local Scalars ..
-      LOGICAL           FIXORD
-      INTEGER           IERR, KI, KR, KT, KTI, KW, NN
-      DOUBLE PRECISION  MAXRED, WRKOPT
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB09AX, TB01ID, TB01WD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, MAX, MIN
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      FIXORD = LSAME( ORDSEL, 'F' )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. LSAME( DICO, 'D' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( LSAME( JOB, 'B' ) .OR. LSAME( JOB, 'N' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( LSAME( EQUIL, 'S' ) .OR.
-     $                 LSAME( EQUIL, 'N' ) ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( FIXORD .AND. ( NR.LT.0 .OR. NR.GT.N ) ) THEN
-         INFO = -8
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -10
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -12
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -14
-      ELSE IF( LDWORK.LT.MAX( 1, N*( 2*N + MAX( N, M, P ) + 5 ) +
-     $                         ( N*( N + 1 ) )/2 ) ) THEN
-         INFO = -19
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09AD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 .OR. ( FIXORD .AND. NR.EQ.0 ) ) THEN
-         NR = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Allocate working storage.
-C
-      NN = N*N
-      KT = 1
-      KR = KT + NN
-      KI = KR + N
-      KW = KI + N
-C
-      IF( LSAME( EQUIL, 'S' ) ) THEN
-C
-C        Scale simultaneously the matrices A, B and C:
-C        A <- inv(D)*A*D,  B <- inv(D)*B and C <- C*D, where D is a
-C        diagonal matrix.
-C
-         MAXRED = C100
-         CALL TB01ID( 'A', N, M, P, MAXRED, A, LDA, B, LDB, C, LDC,
-     $                DWORK, INFO )
-      END IF
-C
-C     Reduce A to the real Schur form using an orthogonal similarity
-C     transformation A <- T'*A*T and apply the transformation to
-C     B and C: B <- T'*B and C <- C*T.
-C
-      CALL TB01WD( N, M, P, A, LDA, B, LDB, C, LDC, DWORK(KT), N,
-     $             DWORK(KR), DWORK(KI), DWORK(KW), LDWORK-KW+1, IERR )
-      IF( IERR.NE.0 ) THEN
-         INFO = 1
-         RETURN
-      END IF
-C
-      WRKOPT = DWORK(KW) + DBLE( KW-1 )
-      KTI = KT  + NN
-      KW  = KTI + NN
-C
-      CALL AB09AX( DICO, JOB, ORDSEL, N, M, P, NR, A, LDA, B, LDB, C,
-     $             LDC, HSV, DWORK(KT), N, DWORK(KTI), N, TOL, IWORK,
-     $             DWORK(KW), LDWORK-KW+1, IWARN, IERR )
-C
-      IF( IERR.NE.0 ) THEN
-         INFO = IERR + 1
-         RETURN
-      END IF
-C
-      DWORK(1) = MAX( WRKOPT, DWORK(KW) + DBLE( KW-1 ) )
-C
-      RETURN
-C *** Last line of AB09AD ***
-      END
--- a/extra/control-devel/src/AB09AX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,564 +0,0 @@
-      SUBROUTINE AB09AX( DICO, JOB, ORDSEL, N, M, P, NR, A, LDA, B, LDB,
-     $                   C, LDC, HSV, T, LDT, TI, LDTI, TOL, IWORK,
-     $                   DWORK, LDWORK, IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order model (Ar,Br,Cr) for a stable original
-C     state-space representation (A,B,C) by using either the square-root
-C     or the balancing-free square-root Balance & Truncate model
-C     reduction method. The state dynamics matrix A of the original
-C     system is an upper quasi-triangular matrix in real Schur canonical
-C     form. The matrices of the reduced order system are computed using
-C     the truncation formulas:
-C
-C          Ar = TI * A * T ,  Br = TI * B ,  Cr = C * T .
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     JOB     CHARACTER*1
-C             Specifies the model reduction approach to be used
-C             as follows:
-C             = 'B':  use the square-root Balance & Truncate method;
-C             = 'N':  use the balancing-free square-root
-C                     Balance & Truncate method.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting order NR is fixed;
-C             = 'A':  the resulting order NR is automatically determined
-C                     on basis of the given tolerance TOL.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation, i.e.
-C             the order of the matrix A.  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     NR      (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NR is the desired order of the
-C             resulting reduced order system.  0 <= NR <= N.
-C             On exit, if INFO = 0, NR is the order of the resulting
-C             reduced order model. NR is set as follows:
-C             if ORDSEL = 'F', NR is equal to MIN(NR,NMIN), where NR
-C             is the desired order on entry and NMIN is the order of a
-C             minimal realization of the given system; NMIN is
-C             determined as the number of Hankel singular values greater
-C             than N*EPS*HNORM(A,B,C), where EPS is the machine
-C             precision (see LAPACK Library Routine DLAMCH) and
-C             HNORM(A,B,C) is the Hankel norm of the system (computed
-C             in HSV(1));
-C             if ORDSEL = 'A', NR is equal to the number of Hankel
-C             singular values greater than MAX(TOL,N*EPS*HNORM(A,B,C)).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A in a real Schur
-C             canonical form.
-C             On exit, if INFO = 0, the leading NR-by-NR part of this
-C             array contains the state dynamics matrix Ar of the
-C             reduced order system.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, if INFO = 0, the leading NR-by-M part of this
-C             array contains the input/state matrix Br of the reduced
-C             order system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, if INFO = 0, the leading P-by-NR part of this
-C             array contains the state/output matrix Cr of the reduced
-C             order system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, it contains the Hankel singular values of
-C             the original system ordered decreasingly. HSV(1) is the
-C             Hankel norm of the system.
-C
-C     T       (output) DOUBLE PRECISION array, dimension (LDT,N)
-C             If INFO = 0 and NR > 0, the leading N-by-NR part of this
-C             array contains the right truncation matrix T.
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.  LDT >= MAX(1,N).
-C
-C     TI      (output) DOUBLE PRECISION array, dimension (LDTI,N)
-C             If INFO = 0 and NR > 0, the leading NR-by-N part of this
-C             array contains the left truncation matrix TI.
-C
-C     LDTI    INTEGER
-C             The leading dimension of array TI.  LDTI >= MAX(1,N).
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL contains the tolerance for
-C             determining the order of reduced system.
-C             For model reduction, the recommended value is
-C             TOL = c*HNORM(A,B,C), where c is a constant in the
-C             interval [0.00001,0.001], and HNORM(A,B,C) is the
-C             Hankel-norm of the given system (computed in HSV(1)).
-C             For computing a minimal realization, the recommended
-C             value is TOL = N*EPS*HNORM(A,B,C), where EPS is the
-C             machine precision (see LAPACK Library Routine DLAMCH).
-C             This value is used by default if TOL <= 0 on entry.
-C             If ORDSEL = 'F', the value of TOL is ignored.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK = 0, if JOB = 'B', or
-C             LIWORK = N, if JOB = 'N'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1,N*(MAX(N,M,P)+5) + N*(N+1)/2).
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NR is greater
-C                   than the order of a minimal realization of the
-C                   given system. In this case, the resulting NR is
-C                   set automatically to a value corresponding to the
-C                   order of a minimal realization of the system.
-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 state matrix A is not stable (if DICO = 'C')
-C                   or not convergent (if DICO = 'D');
-C             = 2:  the computation of Hankel singular values failed.
-C
-C     METHOD
-C
-C     Let be the stable linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t)                               (1)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system. The subroutine AB09AX determines for
-C     the given system (1), the matrices of a reduced NR order system
-C
-C          d[z(t)] = Ar*z(t) + Br*u(t)
-C          yr(t)   = Cr*z(t)                             (2)
-C
-C     such that
-C
-C           HSV(NR) <= INFNORM(G-Gr) <= 2*[HSV(NR+1) + ... + HSV(N)],
-C
-C     where G and Gr are transfer-function matrices of the systems
-C     (A,B,C) and (Ar,Br,Cr), respectively, and INFNORM(G) is the
-C     infinity-norm of G.
-C
-C     If JOB = 'B', the square-root Balance & Truncate method of [1]
-C     is used and, for DICO = 'C', the resulting model is balanced.
-C     By setting TOL <= 0, the routine can be used to compute balanced
-C     minimal state-space realizations of stable systems.
-C
-C     If JOB = 'N', the balancing-free square-root version of the
-C     Balance & Truncate method [2] is used.
-C     By setting TOL <= 0, the routine can be used to compute minimal
-C     state-space realizations of stable systems.
-C
-C     REFERENCES
-C
-C     [1] Tombs M.S. and Postlethwaite I.
-C         Truncated balanced realization of stable, non-minimal
-C         state-space systems.
-C         Int. J. Control, Vol. 46, pp. 1319-1330, 1987.
-C
-C     [2] Varga A.
-C         Efficient minimal realization procedure based on balancing.
-C         Proc. of IMACS/IFAC Symp. MCTS, Lille, France, May 1991,
-C         A. El Moudui, P. Borne, S. G. Tzafestas (Eds.),
-C         Vol. 2, pp. 42-46.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on accuracy enhancing square-root or
-C     balancing-free square-root techniques.
-C                                         3
-C     The algorithms require less than 30N  floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, March 1998.
-C     Based on the RASP routines SRBT1 and SRBFT1.
-C
-C     REVISIONS
-C
-C     May 2, 1998.
-C     November 11, 1998, V. Sima, Research Institute for Informatics,
-C     Bucharest.
-C     December 1998, V. Sima, Katholieke Univ. Leuven, Leuven.
-C     February 14, 1999, A. Varga, German Aerospace Center.
-C     February 22, 1999, V. Sima, Research Institute for Informatics.
-C     February 27, 2000, V. Sima, Research Institute for Informatics.
-C
-C     KEYWORDS
-C
-C     Balancing, minimal state-space representation, model reduction,
-C     multivariable system, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, JOB, ORDSEL
-      INTEGER           INFO, IWARN, LDA, LDB, LDC, LDT, LDTI, LDWORK,
-     $                  M, N, NR, P
-      DOUBLE PRECISION  TOL
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*), HSV(*),
-     $                  T(LDT,*), TI(LDTI,*)
-C     .. Local Scalars ..
-      LOGICAL           BAL, DISCR, FIXORD, PACKED
-      INTEGER           IERR, IJ, J, K, KTAU, KU, KV, KW, LDW, WRKOPT
-      DOUBLE PRECISION  ATOL, RTOL, SCALEC, SCALEO, TEMP
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH
-      EXTERNAL          DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DGEMM, DGEMV, DGEQRF, DGETRF, DGETRS, DLACPY,
-     $                  DORGQR, DSCAL, DTPMV, DTRMM, DTRMV, MA02AD,
-     $                  MA02DD, MB03UD, SB03OU, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, INT, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      DISCR  = LSAME( DICO,   'D' )
-      BAL    = LSAME( JOB,    'B' )
-      FIXORD = LSAME( ORDSEL, 'F' )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( BAL .OR. LSAME( JOB, 'N') ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( FIXORD .AND. ( NR.LT.0 .OR. NR.GT.N ) ) THEN
-         INFO = -7
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -13
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -16
-      ELSE IF( LDTI.LT.MAX( 1, N ) ) THEN
-         INFO = -18
-      ELSE IF( LDWORK.LT.MAX( 1, N*( MAX( N, M, P ) + 5 ) +
-     $                         ( N*( N + 1 ) )/2 ) ) THEN
-         INFO = -22
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09AX', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 .OR. ( FIXORD .AND. NR.EQ.0 ) ) THEN
-         NR = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      RTOL = DBLE( N )*DLAMCH( 'Epsilon' )
-C
-C     Allocate N*MAX(N,M,P) and N working storage for the matrices U
-C     and TAU, respectively.
-C
-      KU   = 1
-      KTAU = KU + N*MAX( N, M, P )
-      KW   = KTAU + N
-      LDW  = LDWORK - KW + 1
-C
-C     Copy B in U.
-C
-      CALL DLACPY( 'Full', N, M, B, LDB, DWORK(KU), N )
-C
-C     If DISCR = .FALSE., solve for Su the Lyapunov equation
-C                                      2
-C     A*(Su*Su') + (Su*Su')*A' + scalec *B*B' = 0 .
-C
-C     If DISCR = .TRUE., solve for Su the Lyapunov equation
-C                           2
-C     A*(Su*Su')*A' + scalec *B*B' = Su*Su' .
-C
-C     Workspace:  need   N*(MAX(N,M,P) + 5);
-C                 prefer larger.
-C
-      CALL SB03OU( DISCR, .TRUE., N, M, A, LDA, DWORK(KU), N,
-     $             DWORK(KTAU), TI, LDTI, SCALEC, DWORK(KW), LDW, IERR )
-      IF( IERR.NE.0 ) THEN
-         INFO = 1
-         RETURN
-      ENDIF
-      WRKOPT = INT( DWORK(KW) ) + KW - 1
-C
-C     Copy C in U.
-C
-      CALL DLACPY( 'Full', P, N, C, LDC, DWORK(KU), P )
-C
-C     If DISCR = .FALSE., solve for Ru the Lyapunov equation
-C                                      2
-C     A'*(Ru'*Ru) + (Ru'*Ru)*A + scaleo  * C'*C = 0 .
-C
-C     If DISCR = .TRUE., solve for Ru the Lyapunov equation
-C                           2
-C     A'*(Ru'*Ru)*A + scaleo  * C'*C = Ru'*Ru .
-C
-C     Workspace:  need   N*(MAX(N,M,P) + 5);
-C                 prefer larger.
-C
-      CALL SB03OU( DISCR, .FALSE., N, P, A, LDA, DWORK(KU), P,
-     $             DWORK(KTAU), T, LDT, SCALEO, DWORK(KW), LDW, IERR )
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Allocate N*(N+1)/2 (or, if possible, N*N) working storage for the
-C     matrix V, a packed (or unpacked) copy of Su, and save Su in V.
-C     (The locations for TAU are reused here.)
-C
-      KV = KTAU
-      IF ( LDWORK-KV+1.LT.N*( N + 5 ) ) THEN
-         PACKED = .TRUE.
-         CALL MA02DD( 'Pack', 'Upper', N, TI, LDTI, DWORK(KV) )
-         KW = KV + ( N*( N + 1 ) )/2
-      ELSE
-         PACKED = .FALSE.
-         CALL DLACPY( 'Upper', N, N, TI, LDTI, DWORK(KV), N )
-         KW = KV + N*N
-      END IF
-C                               | x x |
-C     Compute Ru*Su in the form | 0 x | in TI.
-C
-      DO 10 J = 1, N
-         CALL DTRMV( 'Upper', 'NoTranspose', 'NonUnit', J, T, LDT,
-     $               TI(1,J), 1 )
-   10 CONTINUE
-C
-C     Compute the singular value decomposition Ru*Su = V*S*UT
-C     of the upper triangular matrix Ru*Su, with UT in TI and V in U.
-C
-C     Workspace:  need   N*MAX(N,M,P) + N*(N+1)/2 + 5*N;
-C                 prefer larger.
-C
-      CALL MB03UD( 'Vectors', 'Vectors', N, TI, LDTI, DWORK(KU), N, HSV,
-     $             DWORK(KW), LDWORK-KW+1, IERR )
-      IF( IERR.NE.0 ) THEN
-         INFO = 2
-         RETURN
-      ENDIF
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Scale singular values.
-C
-      CALL DSCAL( N, ONE / SCALEC / SCALEO, HSV, 1 )
-C
-C     Partition S, U and V conformally as:
-C
-C     S = diag(S1,S2),  U = [U1,U2] (U' in TI) and V = [V1,V2] (in U).
-C
-C     Compute the order of reduced system, as the order of S1.
-C
-      ATOL = RTOL*HSV(1)
-      IF( FIXORD ) THEN
-         IF( NR.GT.0 ) THEN
-            IF( HSV(NR).LE.ATOL ) THEN
-               NR = 0
-               IWARN = 1
-               FIXORD = .FALSE.
-            ENDIF
-         ENDIF
-      ELSE
-         ATOL = MAX( TOL, ATOL )
-         NR = 0
-      ENDIF
-      IF( .NOT.FIXORD ) THEN
-         DO 20 J = 1, N
-            IF( HSV(J).LE.ATOL ) GO TO 30
-            NR = NR + 1
-   20    CONTINUE
-   30    CONTINUE
-      ENDIF
-C
-      IF( NR.EQ.0 ) THEN
-         DWORK(1) = WRKOPT
-         RETURN
-      END IF
-C
-C     Compute the truncation matrices.
-C
-C     Compute TI' =  Ru'*V1 in U.
-C
-      CALL DTRMM( 'Left', 'Upper', 'Transpose', 'NonUnit', N, NR, ONE,
-     $             T, LDT, DWORK(KU), N )
-C
-C     Compute T = Su*U1 (with Su packed, if not enough workspace).
-C
-      CALL MA02AD( 'Full', NR, N, TI, LDTI, T, LDT )
-      IF ( PACKED ) THEN
-         DO 40 J = 1, NR
-            CALL DTPMV( 'Upper', 'NoTranspose', 'NonUnit', N, DWORK(KV),
-     $                  T(1,J), 1 )
-   40    CONTINUE
-      ELSE
-         CALL DTRMM( 'Left', 'Upper', 'NoTranspose', 'NonUnit', N, NR,
-     $               ONE, DWORK(KV), N, T, LDT )
-      END IF
-C
-      IF( BAL ) THEN
-         IJ = KU
-C
-C        Square-Root B & T method.
-C
-C        Compute the truncation matrices for balancing
-C                    -1/2           -1/2
-C                T*S1     and TI'*S1
-C
-         DO 50 J = 1, NR
-            TEMP = ONE/SQRT( HSV(J) )
-            CALL DSCAL( N, TEMP, T(1,J), 1 )
-            CALL DSCAL( N, TEMP, DWORK(IJ), 1 )
-            IJ = IJ + N
-   50    CONTINUE
-      ELSE
-C
-C        Balancing-Free B & T method.
-C
-C        Compute orthogonal bases for the images of matrices T and TI'.
-C
-C        Workspace:  need   N*MAX(N,M,P) + 2*NR;
-C                    prefer N*MAX(N,M,P) + NR*(NB+1)
-C                           (NB determined by ILAENV for DGEQRF).
-C
-         KW  = KTAU + NR
-         LDW = LDWORK - KW + 1
-         CALL DGEQRF( N, NR, T, LDT, DWORK(KTAU), DWORK(KW), LDW, IERR )
-         CALL DORGQR( N, NR, NR, T, LDT, DWORK(KTAU), DWORK(KW), LDW,
-     $                IERR )
-         CALL DGEQRF( N, NR, DWORK(KU), N, DWORK(KTAU), DWORK(KW), LDW,
-     $                IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         CALL DORGQR( N, NR, NR, DWORK(KU), N, DWORK(KTAU), DWORK(KW),
-     $                LDW, IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      END IF
-C
-C     Transpose TI' to obtain TI.
-C
-      CALL MA02AD( 'Full', N, NR, DWORK(KU), N, TI, LDTI )
-C
-      IF( .NOT.BAL ) THEN
-C                      -1
-C        Compute (TI*T)  *TI in TI.
-C
-         CALL DGEMM( 'NoTranspose', 'NoTranspose', NR, NR, N, ONE, TI,
-     $               LDTI, T, LDT, ZERO, DWORK(KU), N )
-         CALL DGETRF( NR, NR, DWORK(KU), N, IWORK, IERR )
-         CALL DGETRS( 'NoTranspose', NR, N, DWORK(KU), N, IWORK, TI,
-     $                LDTI, IERR )
-      END IF
-C
-C     Compute TI*A*T (A is in RSF).
-C
-      IJ = KU
-      DO 60 J = 1, N
-         K = MIN( J+1, N )
-         CALL DGEMV( 'NoTranspose', NR, K, ONE, TI, LDTI, A(1,J), 1,
-     $               ZERO, DWORK(IJ), 1 )
-         IJ = IJ + N
-   60 CONTINUE
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NR, NR, N, ONE,
-     $            DWORK(KU), N, T, LDT, ZERO, A, LDA )
-C
-C     Compute TI*B and C*T.
-C
-      CALL DLACPY( 'Full', N, M, B, LDB, DWORK(KU), N )
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NR, M, N, ONE, TI, LDTI,
-     $            DWORK(KU), N, ZERO, B, LDB )
-C
-      CALL DLACPY( 'Full', P, N, C, LDC, DWORK(KU), P )
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', P, NR, N, ONE,
-     $            DWORK(KU), P, T, LDT, ZERO, C, LDC )
-C
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of AB09AX ***
-      END
--- a/extra/control-devel/src/AB09BD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,385 +0,0 @@
-      SUBROUTINE AB09BD( DICO, JOB, EQUIL, ORDSEL, N, M, P, NR, A, LDA,
-     $                   B, LDB, C, LDC, D, LDD, HSV, TOL1, TOL2, IWORK,
-     $                   DWORK, LDWORK, IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order model (Ar,Br,Cr,Dr) for a stable
-C     original state-space representation (A,B,C,D) by using either the
-C     square-root or the balancing-free square-root Singular
-C     Perturbation Approximation (SPA) model reduction method.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     JOB     CHARACTER*1
-C             Specifies the model reduction approach to be used
-C             as follows:
-C             = 'B':  use the square-root SPA method;
-C             = 'N':  use the balancing-free square-root SPA method.
-C
-C     EQUIL   CHARACTER*1
-C             Specifies whether the user wishes to preliminarily
-C             equilibrate the triplet (A,B,C) as follows:
-C             = 'S':  perform equilibration (scaling);
-C             = 'N':  do not perform equilibration.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting order NR is fixed;
-C             = 'A':  the resulting order NR is automatically determined
-C                     on basis of the given tolerance TOL1.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation, i.e.
-C             the order of the matrix A.  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     NR      (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NR is the desired order of
-C             the resulting reduced order system.  0 <= NR <= N.
-C             On exit, if INFO = 0, NR is the order of the resulting
-C             reduced order model. NR is set as follows:
-C             if ORDSEL = 'F', NR is equal to MIN(NR,NMIN), where NR
-C             is the desired order on entry and NMIN is the order of a
-C             minimal realization of the given system; NMIN is
-C             determined as the number of Hankel singular values greater
-C             than N*EPS*HNORM(A,B,C), where EPS is the machine
-C             precision (see LAPACK Library Routine DLAMCH) and
-C             HNORM(A,B,C) is the Hankel norm of the system (computed
-C             in HSV(1));
-C             if ORDSEL = 'A', NR is equal to the number of Hankel
-C             singular values greater than MAX(TOL1,N*EPS*HNORM(A,B,C)).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A.
-C             On exit, if INFO = 0, the leading NR-by-NR part of this
-C             array contains the state dynamics matrix Ar of the
-C             reduced order system.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, if INFO = 0, the leading NR-by-M part of this
-C             array contains the input/state matrix Br of the reduced
-C             order system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, if INFO = 0, the leading P-by-NR part of this
-C             array contains the state/output matrix Cr of the reduced
-C             order system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the original input/output matrix D.
-C             On exit, if INFO = 0, the leading P-by-M part of this
-C             array contains the input/output matrix Dr of the reduced
-C             order system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, it contains the Hankel singular values of
-C             the original system ordered decreasingly. HSV(1) is the
-C             Hankel norm of the system.
-C
-C     Tolerances
-C
-C     TOL1    DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL1 contains the tolerance for
-C             determining the order of reduced system.
-C             For model reduction, the recommended value is
-C             TOL1 = c*HNORM(A,B,C), where c is a constant in the
-C             interval [0.00001,0.001], and HNORM(A,B,C) is the
-C             Hankel-norm of the given system (computed in HSV(1)).
-C             For computing a minimal realization, the recommended
-C             value is TOL1 = N*EPS*HNORM(A,B,C), where EPS is the
-C             machine precision (see LAPACK Library Routine DLAMCH).
-C             This value is used by default if TOL1 <= 0 on entry.
-C             If ORDSEL = 'F', the value of TOL1 is ignored.
-C
-C     TOL2    DOUBLE PRECISION
-C             The tolerance for determining the order of a minimal
-C             realization of the given system. The recommended value is
-C             TOL2 = N*EPS*HNORM(A,B,C). This value is used by default
-C             if TOL2 <= 0 on entry.
-C             If TOL2 > 0, then TOL2 <= TOL1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension MAX(1,2*N)
-C             On exit with INFO = 0, IWORK(1) contains the order of the
-C             minimal realization of the system.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1,N*(2*N+MAX(N,M,P)+5)+N*(N+1)/2).
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NR is greater
-C                   than the order of a minimal realization of the
-C                   given system. In this case, the resulting NR is
-C                   set automatically to a value corresponding to the
-C                   order of a minimal realization of the system.
-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 reduction of A to the real Schur form failed;
-C             = 2:  the state matrix A is not stable (if DICO = 'C')
-C                   or not convergent (if DICO = 'D');
-C             = 3:  the computation of Hankel singular values failed.
-C
-C     METHOD
-C
-C     Let be the stable linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t) + Du(t)                           (1)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system. The subroutine AB09BD determines for
-C     the given system (1), the matrices of a reduced order system
-C
-C          d[z(t)] = Ar*z(t) + Br*u(t)
-C          yr(t)   = Cr*z(t) + Dr*u(t)                       (2)
-C
-C     such that
-C
-C           HSV(NR) <= INFNORM(G-Gr) <= 2*[HSV(NR+1) + ... + HSV(N)],
-C
-C     where G and Gr are transfer-function matrices of the systems
-C     (A,B,C,D) and (Ar,Br,Cr,Dr), respectively, and INFNORM(G) is the
-C     infinity-norm of G.
-C
-C     If JOB = 'B', the balancing-based square-root SPA method of [1]
-C     is used and the resulting model is balanced.
-C
-C     If JOB = 'N', the balancing-free square-root SPA method of [2]
-C     is used.
-C     By setting TOL1 = TOL2, the routine can be used to compute
-C     Balance & Truncate approximations.
-C
-C     REFERENCES
-C
-C     [1] Liu Y. and Anderson B.D.O.
-C         Singular Perturbation Approximation of Balanced Systems,
-C         Int. J. Control, Vol. 50, pp. 1379-1405, 1989.
-C
-C     [2] Varga A.
-C         Balancing-free square-root algorithm for computing singular
-C         perturbation approximations.
-C         Proc. 30-th IEEE CDC,  Brighton, Dec. 11-13, 1991,
-C         Vol. 2, pp. 1062-1065.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on accuracy enhancing square-root or
-C     balancing-free square-root techniques.
-C                                         3
-C     The algorithms require less than 30N  floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     C. Oara and A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, March 1998.
-C     Based on the RASP routine SRBFSP.
-C
-C     REVISIONS
-C
-C     May 2, 1998.
-C     November 11, 1998, V. Sima, Research Institute for Informatics,
-C     Bucharest.
-C
-C     KEYWORDS
-C
-C     Balancing, minimal state-space representation, model reduction,
-C     multivariable system, singular perturbation approximation,
-C     state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE, C100
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0, C100 = 100.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, EQUIL, JOB, ORDSEL
-      INTEGER           INFO, IWARN, LDA, LDB, LDC, LDD, LDWORK,
-     $                  M, N, NR, P
-      DOUBLE PRECISION  TOL1, TOL2
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                  DWORK(*), HSV(*)
-C     .. Local Scalars ..
-      LOGICAL           FIXORD
-      INTEGER           IERR, KI, KR, KT, KTI, KW, NN
-      DOUBLE PRECISION  MAXRED, WRKOPT
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB09BX, TB01ID, TB01WD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, MAX, MIN
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      FIXORD = LSAME( ORDSEL, 'F' )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. LSAME( DICO, 'D' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( LSAME( JOB, 'B' ) .OR. LSAME( JOB, 'N' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( LSAME( EQUIL, 'S' ) .OR.
-     $                 LSAME( EQUIL, 'N' ) ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( FIXORD .AND. ( NR.LT.0 .OR. NR.GT.N ) ) THEN
-         INFO = -8
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -10
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -12
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -14
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -16
-      ELSE IF( TOL2.GT.ZERO .AND. TOL2.GT.TOL1 ) THEN
-         INFO = -19
-      ELSE IF( LDWORK.LT.MAX( 1, N*( 2*N + MAX( N, M, P ) + 5 ) +
-     $                         ( N*( N + 1 ) )/2 ) ) THEN
-         INFO = -22
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09BD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 ) THEN
-         NR = 0
-         IWORK(1) = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Allocate working storage.
-C
-      NN = N*N
-      KT = 1
-      KR = KT + NN
-      KI = KR + N
-      KW = KI + N
-C
-      IF( LSAME( EQUIL, 'S' ) ) THEN
-C
-C        Scale simultaneously the matrices A, B and C:
-C        A <- inv(D)*A*D,  B <- inv(D)*B and C <- C*D, where D is a
-C        diagonal matrix.
-C
-         MAXRED = C100
-         CALL TB01ID( 'All', N, M, P, MAXRED, A, LDA, B, LDB, C, LDC,
-     $                DWORK, INFO )
-      END IF
-C
-C     Reduce A to the real Schur form using an orthogonal similarity
-C     transformation A <- T'*A*T and apply the transformation to
-C     B and C: B <- T'*B and C <- C*T.
-C
-      CALL TB01WD( N, M, P, A, LDA, B, LDB, C, LDC, DWORK(KT), N,
-     $             DWORK(KR), DWORK(KI), DWORK(KW), LDWORK-KW+1, IERR )
-      IF( IERR.NE.0 ) THEN
-         INFO = 1
-         RETURN
-      END IF
-C
-      WRKOPT = DWORK(KW) + DBLE( KW-1 )
-C
-      KTI = KT  + NN
-      KW  = KTI + NN
-      CALL AB09BX( DICO, JOB, ORDSEL, N, M, P, NR, A, LDA, B, LDB,
-     $             C, LDC, D, LDD, HSV, DWORK(KT), N, DWORK(KTI), N,
-     $             TOL1, TOL2, IWORK, DWORK(KW), LDWORK-KW+1, IWARN,
-     $             IERR )
-C
-      IF( IERR.NE.0 ) THEN
-         INFO = IERR + 1
-         RETURN
-      END IF
-C
-      DWORK(1) = MAX( WRKOPT, DWORK(KW) + DBLE( KW-1 ) )
-C
-      RETURN
-C *** Last line of AB09BD ***
-      END
--- a/extra/control-devel/src/AB09BX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,662 +0,0 @@
-      SUBROUTINE AB09BX( DICO, JOB, ORDSEL, N, M, P, NR, A, LDA, B, LDB,
-     $                   C, LDC, D, LDD, HSV, T, LDT, TI, LDTI, TOL1,
-     $                   TOL2, IWORK, DWORK, LDWORK, IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order model (Ar,Br,Cr,Dr) for a stable
-C     original state-space representation (A,B,C,D) by using either the
-C     square-root or the balancing-free square-root
-C     Singular Perturbation Approximation (SPA) model reduction method.
-C     The state dynamics matrix A of the original system is an upper
-C     quasi-triangular matrix in real Schur canonical form. The matrices
-C     of a minimal realization are computed using the truncation
-C     formulas:
-C
-C          Am = TI * A * T ,  Bm = TI * B ,  Cm = C * T .      (1)
-C
-C     Am, Bm, Cm and D serve further for computing the SPA of the given
-C     system.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     JOB     CHARACTER*1
-C             Specifies the model reduction approach to be used
-C             as follows:
-C             = 'B':  use the square-root SPA method;
-C             = 'N':  use the balancing-free square-root SPA method.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting order NR is fixed;
-C             = 'A':  the resulting order NR is automatically determined
-C                     on basis of the given tolerance TOL1.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation, i.e.
-C             the order of the matrix A.  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     NR      (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NR is the desired order of
-C             the resulting reduced order system.  0 <= NR <= N.
-C             On exit, if INFO = 0, NR is the order of the resulting
-C             reduced order model. NR is set as follows:
-C             if ORDSEL = 'F', NR is equal to MIN(NR,NMIN), where NR
-C             is the desired order on entry and NMIN is the order of a
-C             minimal realization of the given system; NMIN is
-C             determined as the number of Hankel singular values greater
-C             than N*EPS*HNORM(A,B,C), where EPS is the machine
-C             precision (see LAPACK Library Routine DLAMCH) and
-C             HNORM(A,B,C) is the Hankel norm of the system (computed
-C             in HSV(1));
-C             if ORDSEL = 'A', NR is equal to the number of Hankel
-C             singular values greater than MAX(TOL1,N*EPS*HNORM(A,B,C)).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A in a real Schur
-C             canonical form.
-C             On exit, if INFO = 0, the leading NR-by-NR part of this
-C             array contains the state dynamics matrix Ar of the
-C             reduced order system.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, if INFO = 0, the leading NR-by-M part of this
-C             array contains the input/state matrix Br of the reduced
-C             order system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, if INFO = 0, the leading P-by-NR part of this
-C             array contains the state/output matrix Cr of the reduced
-C             order system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the original input/output matrix D.
-C             On exit, if INFO = 0, the leading P-by-M part of this
-C             array contains the input/output matrix Dr of the reduced
-C             order system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, it contains the Hankel singular values of
-C             the original system ordered decreasingly. HSV(1) is the
-C             Hankel norm of the system.
-C
-C     T       (output) DOUBLE PRECISION array, dimension (LDT,N)
-C             If INFO = 0 and NR > 0, the leading N-by-NR part of this
-C             array contains the right truncation matrix T in (1).
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.  LDT >= MAX(1,N).
-C
-C     TI      (output) DOUBLE PRECISION array, dimension (LDTI,N)
-C             If INFO = 0 and NR > 0, the leading NR-by-N part of this
-C             array contains the left truncation matrix TI in (1).
-C
-C     LDTI    INTEGER
-C             The leading dimension of array TI.  LDTI >= MAX(1,N).
-C
-C     Tolerances
-C
-C     TOL1    DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL1 contains the tolerance for
-C             determining the order of reduced system.
-C             For model reduction, the recommended value is
-C             TOL1 = c*HNORM(A,B,C), where c is a constant in the
-C             interval [0.00001,0.001], and HNORM(A,B,C) is the
-C             Hankel-norm of the given system (computed in HSV(1)).
-C             For computing a minimal realization, the recommended
-C             value is TOL1 = N*EPS*HNORM(A,B,C), where EPS is the
-C             machine precision (see LAPACK Library Routine DLAMCH).
-C             This value is used by default if TOL1 <= 0 on entry.
-C             If ORDSEL = 'F', the value of TOL1 is ignored.
-C
-C     TOL2    DOUBLE PRECISION
-C             The tolerance for determining the order of a minimal
-C             realization of the given system. The recommended value is
-C             TOL2 = N*EPS*HNORM(A,B,C). This value is used by default
-C             if TOL2 <= 0 on entry.
-C             If TOL2 > 0, then TOL2 <= TOL1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension MAX(1,2*N)
-C             On exit with INFO = 0, IWORK(1) contains the order of the
-C             minimal realization of the system.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1,N*(MAX(N,M,P)+5) + N*(N+1)/2).
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NR is greater
-C                   than the order of a minimal realization of the
-C                   given system. In this case, the resulting NR is
-C                   set automatically to a value corresponding to the
-C                   order of a minimal realization of the system.
-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 state matrix A is not stable (if DICO = 'C')
-C                   or not convergent (if DICO = 'D');
-C             = 2:  the computation of Hankel singular values failed.
-C
-C     METHOD
-C
-C     Let be the stable linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t) + Du(t)                              (2)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system. The subroutine AB09BX determines for
-C     the given system (1), the matrices of a reduced NR order system
-C
-C          d[z(t)] = Ar*z(t) + Br*u(t)
-C          yr(t)   = Cr*z(t) + Dr*u(t)                          (3)
-C
-C     such that
-C
-C           HSV(NR) <= INFNORM(G-Gr) <= 2*[HSV(NR+1) + ... + HSV(N)],
-C
-C     where G and Gr are transfer-function matrices of the systems
-C     (A,B,C,D) and (Ar,Br,Cr,Dr), respectively, and INFNORM(G) is the
-C     infinity-norm of G.
-C
-C     If JOB = 'B', the balancing-based square-root SPA method of [1]
-C     is used and the resulting model is balanced.
-C
-C     If JOB = 'N', the balancing-free square-root SPA method of [2]
-C     is used.
-C     By setting TOL1 = TOL2, the routine can be also used to compute
-C     Balance & Truncate approximations.
-C
-C     REFERENCES
-C
-C     [1] Liu Y. and Anderson B.D.O.
-C         Singular Perturbation Approximation of Balanced Systems,
-C         Int. J. Control, Vol. 50, pp. 1379-1405, 1989.
-C
-C     [2] Varga A.
-C         Balancing-free square-root algorithm for computing singular
-C         perturbation approximations.
-C         Proc. 30-th IEEE CDC,  Brighton, Dec. 11-13, 1991,
-C         Vol. 2, pp. 1062-1065.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on accuracy enhancing square-root or
-C     balancing-free square-root techniques.
-C                                         3
-C     The algorithms require less than 30N  floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, March 1998.
-C     Based on the RASP routine SRBFP1.
-C
-C     REVISIONS
-C
-C     May 2, 1998.
-C     November 11, 1998, V. Sima, Research Institute for Informatics,
-C     Bucharest.
-C     December 1998, V. Sima, Katholieke Univ. Leuven, Leuven.
-C     February 14, 1999, A. Varga, German Aerospace Center.
-C     February 22, 1999, V. Sima, Research Institute for Informatics.
-C     February 27, 2000, V. Sima, Research Institute for Informatics.
-C     May 26, 2000, A. Varga, German Aerospace Center.
-C
-C     KEYWORDS
-C
-C     Balancing, minimal state-space representation, model reduction,
-C     multivariable system, singular perturbation approximation,
-C     state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, JOB, ORDSEL
-      INTEGER           INFO, IWARN, LDA, LDB, LDC, LDD, LDT, LDTI,
-     $                  LDWORK, M, N, NR, P
-      DOUBLE PRECISION  TOL1, TOL2
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                  DWORK(*), HSV(*), T(LDT,*), TI(LDTI,*)
-C     .. Local Scalars ..
-      LOGICAL           BAL, DISCR, FIXORD, PACKED
-      INTEGER           IERR, IJ, J, K, KTAU, KU, KV, KW, LDW, NMINR,
-     $                  NR1, NS, WRKOPT
-      DOUBLE PRECISION  ATOL, RCOND, RTOL, SCALEC, SCALEO, TEMP
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH
-      EXTERNAL          DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB09DD, DGEMM, DGEMV, DGEQRF, DGETRF, DGETRS,
-     $                  DLACPY, DORGQR, DSCAL, DTPMV, DTRMM, DTRMV,
-     $                  MA02AD, MA02DD, MB03UD, SB03OU, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, INT, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      DISCR  = LSAME( DICO,   'D' )
-      BAL    = LSAME( JOB,    'B' )
-      FIXORD = LSAME( ORDSEL, 'F' )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( BAL .OR. LSAME( JOB, 'N') ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( FIXORD .AND. ( NR.LT.0 .OR. NR.GT.N ) ) THEN
-         INFO = -7
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -13
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -15
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -18
-      ELSE IF( LDTI.LT.MAX( 1, N ) ) THEN
-         INFO = -20
-      ELSE IF( TOL2.GT.ZERO .AND. TOL2.GT.TOL1 ) THEN
-         INFO = -22
-      ELSE IF( LDWORK.LT.MAX( 1, N*( MAX( N, M, P ) + 5 ) +
-     $                         ( N*( N + 1 ) )/2 ) ) THEN
-         INFO = -25
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09BX', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 ) THEN
-         NR = 0
-         IWORK(1) = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      RTOL = DBLE( N )*DLAMCH( 'Epsilon' )
-C
-C     Allocate N*MAX(N,M,P) and N working storage for the matrices U
-C     and TAU, respectively.
-C
-      KU   = 1
-      KTAU = KU + N*MAX( N, M, P )
-      KW   = KTAU + N
-      LDW  = LDWORK - KW + 1
-C
-C     Copy B in U.
-C
-      CALL DLACPY( 'Full', N, M, B, LDB, DWORK(KU), N )
-C
-C     If DISCR = .FALSE., solve for Su the Lyapunov equation
-C                                      2
-C     A*(Su*Su') + (Su*Su')*A' + scalec *B*B' = 0 .
-C
-C     If DISCR = .TRUE., solve for Su the Lyapunov equation
-C                           2
-C     A*(Su*Su')*A' + scalec *B*B' = Su*Su' .
-C
-C     Workspace:  need   N*(MAX(N,M,P) + 5);
-C                 prefer larger.
-C
-      CALL SB03OU( DISCR, .TRUE., N, M, A, LDA, DWORK(KU), N,
-     $             DWORK(KTAU), TI, LDTI, SCALEC, DWORK(KW), LDW, IERR )
-      IF( IERR.NE.0 ) THEN
-         INFO = 1
-         RETURN
-      ENDIF
-      WRKOPT = INT( DWORK(KW) ) + KW - 1
-C
-C     Copy C in U.
-C
-      CALL DLACPY( 'Full', P, N, C, LDC, DWORK(KU), P )
-C
-C     If DISCR = .FALSE., solve for Ru the Lyapunov equation
-C                                      2
-C     A'*(Ru'*Ru) + (Ru'*Ru)*A + scaleo  * C'*C = 0 .
-C
-C     If DISCR = .TRUE., solve for Ru the Lyapunov equation
-C                           2
-C     A'*(Ru'*Ru)*A + scaleo  * C'*C = Ru'*Ru .
-C
-C     Workspace:  need   N*(MAX(N,M,P) + 5);
-C                 prefer larger.
-C
-      CALL SB03OU( DISCR, .FALSE., N, P, A, LDA, DWORK(KU), P,
-     $             DWORK(KTAU), T, LDT, SCALEO, DWORK(KW), LDW, IERR )
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Allocate N*(N+1)/2 (or, if possible, N*N) working storage for the
-C     matrix V, a packed (or unpacked) copy of Su, and save Su in V.
-C     (The locations for TAU are reused here.)
-C
-      KV = KTAU
-      IF ( LDWORK-KV+1.LT.N*( N + 5 ) ) THEN
-         PACKED = .TRUE.
-         CALL MA02DD( 'Pack', 'Upper', N, TI, LDTI, DWORK(KV) )
-         KW = KV + ( N*( N + 1 ) )/2
-      ELSE
-         PACKED = .FALSE.
-         CALL DLACPY( 'Upper', N, N, TI, LDTI, DWORK(KV), N )
-         KW = KV + N*N
-      END IF
-C                               | x x |
-C     Compute Ru*Su in the form | 0 x | in TI.
-C
-      DO 10 J = 1, N
-         CALL DTRMV( 'Upper', 'NoTranspose', 'NonUnit', J, T, LDT,
-     $               TI(1,J), 1 )
-   10 CONTINUE
-C
-C     Compute the singular value decomposition Ru*Su = V*S*UT
-C     of the upper triangular matrix Ru*Su, with UT in TI and V in U.
-C
-C     Workspace:  need   N*MAX(N,M,P) + N*(N+1)/2 + 5*N;
-C                 prefer larger.
-C
-      CALL MB03UD( 'Vectors', 'Vectors', N, TI, LDTI, DWORK(KU), N, HSV,
-     $             DWORK(KW), LDWORK-KW+1, IERR )
-      IF( IERR.NE.0 ) THEN
-         INFO = 2
-         RETURN
-      ENDIF
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Scale singular values.
-C
-      CALL DSCAL( N, ONE / SCALEC / SCALEO, HSV, 1 )
-C
-C     Partition S, U and V conformally as:
-C
-C     S = diag(S1,S2,S3),  U = [U1,U2,U3] (U' in TI) and V = [V1,V2,V3]
-C     (in U).
-C
-C     Compute the order NR of reduced system, as the order of S1.
-C
-      ATOL = RTOL*HSV(1)
-      IF( FIXORD ) THEN
-         IF( NR.GT.0 ) THEN
-            IF( HSV(NR).LE.ATOL ) THEN
-               NR = 0
-               IWARN = 1
-               FIXORD = .FALSE.
-            ENDIF
-         ENDIF
-      ELSE
-         ATOL = MAX( TOL1, ATOL )
-         NR = 0
-      ENDIF
-      IF( .NOT.FIXORD ) THEN
-         DO 20 J = 1, N
-            IF( HSV(J).LE.ATOL ) GO TO 30
-            NR = NR + 1
-   20    CONTINUE
-   30    CONTINUE
-      ENDIF
-C
-C     Finish if the order of the reduced model is zero.
-C
-      IF( NR.EQ.0 ) THEN
-C
-C       Compute only Dr using singular perturbation formulas.
-C       Workspace:  need real    4*N;
-C                   need integer 2*N.
-C
-         CALL AB09DD( DICO, N, M, P, NR, A, LDA, B, LDB, C, LDC, D,
-     $                LDD, RCOND, IWORK, DWORK, IERR )
-         IWORK(1) = 0
-         DWORK(1) = WRKOPT
-         RETURN
-      END IF
-C
-C     Compute the order of minimal realization as the order of [S1 S2].
-C
-      NR1 = NR + 1
-      NMINR = NR
-      IF( NR.LT.N ) THEN
-         ATOL = MAX( TOL2, RTOL*HSV(1) )
-         DO 40 J = NR1, N
-            IF( HSV(J).LE.ATOL ) GO TO 50
-            NMINR = NMINR + 1
-   40    CONTINUE
-   50    CONTINUE
-      END IF
-C
-C     Compute the order of S2.
-C
-      NS = NMINR - NR
-C
-C     Compute the truncation matrices.
-C
-C     Compute TI' = | TI1' TI2' | = Ru'*| V1 V2 | in U.
-C
-      CALL DTRMM( 'Left', 'Upper', 'Transpose', 'NonUnit', N, NMINR,
-     $            ONE, T, LDT, DWORK(KU), N )
-C
-C     Compute  T = | T1 T2 | = Su*| U1 U2 |
-C     (with Su packed, if not enough workspace).
-C
-      CALL MA02AD( 'Full', NMINR, N, TI, LDTI, T, LDT )
-      IF ( PACKED ) THEN
-         DO 60 J = 1, NMINR
-            CALL DTPMV( 'Upper', 'NoTranspose', 'NonUnit', N, DWORK(KV),
-     $                  T(1,J), 1 )
-   60    CONTINUE
-      ELSE
-         CALL DTRMM( 'Left', 'Upper', 'NoTranspose', 'NonUnit', N,
-     $               NMINR, ONE, DWORK(KV), N, T, LDT )
-      END IF
-C
-      IF( BAL ) THEN
-         IJ = KU
-C
-C        Square-Root SPA method.
-C
-C        Compute the truncation matrices for balancing
-C                    -1/2            -1/2
-C               T1*S1     and TI1'*S1
-C
-         DO 70 J = 1, NR
-            TEMP = ONE/SQRT( HSV(J) )
-            CALL DSCAL( N, TEMP, T(1,J), 1 )
-            CALL DSCAL( N, TEMP, DWORK(IJ), 1 )
-            IJ = IJ + N
-   70    CONTINUE
-      ELSE
-C
-C        Balancing-Free SPA method.
-C
-C        Compute orthogonal bases for the images of matrices T1 and
-C        TI1'.
-C
-C        Workspace:  need   N*MAX(N,M,P) + 2*NR;
-C                    prefer N*MAX(N,M,P) + NR*(NB+1)
-C                           (NB determined by ILAENV for DGEQRF).
-C
-         KW  = KTAU + NR
-         LDW = LDWORK - KW + 1
-         CALL DGEQRF( N, NR, T, LDT, DWORK(KTAU), DWORK(KW), LDW, IERR )
-         CALL DORGQR( N, NR, NR, T, LDT, DWORK(KTAU), DWORK(KW), LDW,
-     $                IERR )
-         CALL DGEQRF( N, NR, DWORK(KU), N, DWORK(KTAU), DWORK(KW), LDW,
-     $                IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         CALL DORGQR( N, NR, NR, DWORK(KU), N, DWORK(KTAU), DWORK(KW),
-     $                LDW, IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      ENDIF
-      IF( NS.GT.0 ) THEN
-C
-C        Compute orthogonal bases for the images of matrices T2 and
-C        TI2'.
-C
-C        Workspace:  need   N*MAX(N,M,P) + 2*NS;
-C                    prefer N*MAX(N,M,P) + NS*(NB+1)
-C                           (NB determined by ILAENV for DGEQRF).
-         KW  = KTAU + NS
-         LDW = LDWORK - KW + 1
-         CALL DGEQRF( N, NS, T(1,NR1), LDT, DWORK(KTAU), DWORK(KW), LDW,
-     $                IERR )
-         CALL DORGQR( N, NS, NS, T(1,NR1), LDT, DWORK(KTAU), DWORK(KW),
-     $                LDW, IERR )
-         CALL DGEQRF( N, NS, DWORK(KU+N*NR), N, DWORK(KTAU), DWORK(KW),
-     $                LDW, IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         CALL DORGQR( N, NS, NS, DWORK(KU+N*NR), N, DWORK(KTAU),
-     $                DWORK(KW), LDW, IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      ENDIF
-C
-C     Transpose TI' in TI.
-C
-      CALL MA02AD( 'Full', N, NMINR, DWORK(KU), N, TI, LDTI )
-C
-      IF( .NOT.BAL ) THEN
-C                        -1
-C        Compute (TI1*T1)  *TI1 in TI.
-C
-         CALL DGEMM( 'NoTranspose', 'NoTranspose', NR, NR, N, ONE, TI,
-     $               LDTI, T, LDT, ZERO, DWORK(KU), N )
-         CALL DGETRF( NR, NR, DWORK(KU), N, IWORK, IERR )
-         CALL DGETRS( 'NoTranspose', NR, N, DWORK(KU), N, IWORK, TI,
-     $                LDTI, IERR )
-C
-         IF( NS.GT.0 ) THEN
-C                           -1
-C           Compute (TI2*T2)  *TI2 in TI2.
-C
-            CALL DGEMM( 'NoTranspose', 'NoTranspose', NS, NS, N, ONE,
-     $                  TI(NR1,1), LDTI, T(1,NR1), LDT, ZERO, DWORK(KU),
-     $                  N )
-            CALL DGETRF( NS, NS, DWORK(KU), N, IWORK, IERR )
-            CALL DGETRS( 'NoTranspose', NS, N, DWORK(KU), N, IWORK,
-     $                   TI(NR1,1), LDTI, IERR )
-         END IF
-      END IF
-C
-C     Compute TI*A*T (A is in RSF).
-C
-      IJ = KU
-      DO 80 J = 1, N
-         K = MIN( J+1, N )
-         CALL DGEMV( 'NoTranspose', NMINR, K, ONE, TI, LDTI, A(1,J), 1,
-     $               ZERO, DWORK(IJ), 1 )
-         IJ = IJ + N
-   80 CONTINUE
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NMINR, NMINR, N, ONE,
-     $            DWORK(KU), N, T, LDT, ZERO, A, LDA )
-C
-C     Compute TI*B and C*T.
-C
-      CALL DLACPY( 'Full', N, M, B, LDB, DWORK(KU), N )
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NMINR, M, N, ONE, TI,
-     $            LDTI, DWORK(KU), N, ZERO, B, LDB )
-C
-      CALL DLACPY( 'Full', P, N, C, LDC, DWORK(KU), P )
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', P, NMINR, N, ONE,
-     $            DWORK(KU), P, T, LDT, ZERO, C, LDC )
-C
-C     Compute the singular perturbation approximation if possible.
-C     Note that IERR = 1 on exit from AB09DD cannot appear here.
-C
-C     Workspace:  need real    4*(NMINR-NR);
-C                 need integer 2*(NMINR-NR).
-C
-      CALL AB09DD( DICO, NMINR, M, P, NR, A, LDA, B, LDB, C, LDC, D,
-     $             LDD, RCOND, IWORK, DWORK, IERR )
-C
-      IWORK(1) = NMINR
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of AB09BX ***
-      END
--- a/extra/control-devel/src/AB09CX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,558 +0,0 @@
-      SUBROUTINE AB09CX( DICO, ORDSEL, N, M, P, NR, A, LDA, B, LDB,
-     $                   C, LDC, D, LDD, HSV, TOL1, TOL2, IWORK,
-     $                   DWORK, LDWORK, IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order model (Ar,Br,Cr,Dr) for a stable
-C     original state-space representation (A,B,C,D) by using the optimal
-C     Hankel-norm approximation method in conjunction with square-root
-C     balancing. The state dynamics matrix A of the original system is
-C     an upper quasi-triangular matrix in real Schur canonical form.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting order NR is fixed;
-C             = 'A':  the resulting order NR is automatically determined
-C                     on basis of the given tolerance TOL1.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation, i.e.
-C             the order of the matrix A.  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     NR      (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NR is the desired order of
-C             the resulting reduced order system.  0 <= NR <= N.
-C             On exit, if INFO = 0, NR is the order of the resulting
-C             reduced order model. NR is set as follows:
-C             if ORDSEL = 'F', NR is equal to MIN(MAX(0,NR-KR+1),NMIN),
-C             where KR is the multiplicity of the Hankel singular value
-C             HSV(NR+1), NR is the desired order on entry, and NMIN is
-C             the order of a minimal realization of the given system;
-C             NMIN is determined as the number of Hankel singular values
-C             greater than N*EPS*HNORM(A,B,C), where EPS is the machine
-C             precision (see LAPACK Library Routine DLAMCH) and
-C             HNORM(A,B,C) is the Hankel norm of the system (computed
-C             in HSV(1));
-C             if ORDSEL = 'A', NR is equal to the number of Hankel
-C             singular values greater than MAX(TOL1,N*EPS*HNORM(A,B,C)).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A in a real Schur
-C             canonical form.
-C             On exit, if INFO = 0, the leading NR-by-NR part of this
-C             array contains the state dynamics matrix Ar of the
-C             reduced order system in a real Schur form.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, if INFO = 0, the leading NR-by-M part of this
-C             array contains the input/state matrix Br of the reduced
-C             order system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, if INFO = 0, the leading P-by-NR part of this
-C             array contains the state/output matrix Cr of the reduced
-C             order system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the original input/output matrix D.
-C             On exit, if INFO = 0, the leading P-by-M part of this
-C             array contains the input/output matrix Dr of the reduced
-C             order system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, it contains the Hankel singular values of
-C             the original system ordered decreasingly. HSV(1) is the
-C             Hankel norm of the system.
-C
-C     Tolerances
-C
-C     TOL1    DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL1 contains the tolerance for
-C             determining the order of reduced system.
-C             For model reduction, the recommended value is
-C             TOL1 = c*HNORM(A,B,C), where c is a constant in the
-C             interval [0.00001,0.001], and HNORM(A,B,C) is the
-C             Hankel-norm of the given system (computed in HSV(1)).
-C             For computing a minimal realization, the recommended
-C             value is TOL1 = N*EPS*HNORM(A,B,C), where EPS is the
-C             machine precision (see LAPACK Library Routine DLAMCH).
-C             This value is used by default if TOL1 <= 0 on entry.
-C             If ORDSEL = 'F', the value of TOL1 is ignored.
-C
-C     TOL2    DOUBLE PRECISION
-C             The tolerance for determining the order of a minimal
-C             realization of the given system. The recommended value is
-C             TOL2 = N*EPS*HNORM(A,B,C). This value is used by default
-C             if TOL2 <= 0 on entry.
-C             If TOL2 > 0, then TOL2 <= TOL1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK = MAX(1,M),   if DICO = 'C';
-C             LIWORK = MAX(1,N,M), if DICO = 'D'.
-C             On exit, if INFO = 0, IWORK(1) contains NMIN, the order of
-C             the computed minimal realization.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX( LDW1,LDW2 ), where
-C             LDW1 = N*(2*N+MAX(N,M,P)+5) + N*(N+1)/2,
-C             LDW2 = N*(M+P+2) + 2*M*P + MIN(N,M) +
-C                    MAX( 3*M+1, MIN(N,M)+P ).
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NR is greater
-C                   than the order of a minimal realization of the
-C                   given system. In this case, the resulting NR is set
-C                   automatically to a value corresponding to the order
-C                   of a minimal realization of the system.
-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 state matrix A is not stable (if DICO = 'C')
-C                   or not convergent (if DICO = 'D');
-C             = 2:  the computation of Hankel singular values failed;
-C             = 3:  the computation of stable projection failed;
-C             = 4:  the order of computed stable projection differs
-C                   from the order of Hankel-norm approximation.
-C
-C     METHOD
-C
-C     Let be the stable linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t) + Du(t)                           (1)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system. The subroutine AB09CX determines for
-C     the given system (1), the matrices of a reduced order system
-C
-C          d[z(t)] = Ar*z(t) + Br*u(t)
-C          yr(t)   = Cr*z(t) + Dr*u(t)                       (2)
-C
-C     such that
-C
-C           HSV(NR) <= INFNORM(G-Gr) <= 2*[HSV(NR+1) + ... + HSV(N)],
-C
-C     where G and Gr are transfer-function matrices of the systems
-C     (A,B,C,D) and (Ar,Br,Cr,Dr), respectively, and INFNORM(G) is the
-C     infinity-norm of G.
-C
-C     The optimal Hankel-norm approximation method of [1], based on the
-C     square-root balancing projection formulas of [2], is employed.
-C
-C     REFERENCES
-C
-C     [1] Glover, K.
-C         All optimal Hankel norm approximation of linear
-C         multivariable systems and their L-infinity error bounds.
-C         Int. J. Control, Vol. 36, pp. 1145-1193, 1984.
-C
-C     [2] Tombs M.S. and Postlethwaite I.
-C         Truncated balanced realization of stable, non-minimal
-C         state-space systems.
-C         Int. J. Control, Vol. 46, pp. 1319-1330, 1987.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on an accuracy enhancing square-root
-C     technique.
-C                                         3
-C     The algorithms require less than 30N  floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, April 1998.
-C     Based on the RASP routine OHNAP1.
-C
-C     REVISIONS
-C
-C     November 11, 1998, V. Sima, Research Institute for Informatics,
-C     Bucharest.
-C     April 24, 2000, A. Varga, DLR Oberpfaffenhofen.
-C     April  8, 2001, A. Varga, DLR Oberpfaffenhofen.
-C     March 26, 2005, V. Sima, Research Institute for Informatics.
-C
-C     KEYWORDS
-C
-C     Balancing, Hankel-norm approximation, model reduction,
-C     multivariable system, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, ORDSEL
-      INTEGER           INFO, IWARN, LDA, LDB, LDC, LDD, LDWORK,
-     $                  M, N, NR, P
-      DOUBLE PRECISION  TOL1, TOL2
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                  DWORK(*), HSV(*)
-C     .. Local Scalars
-      LOGICAL           DISCR, FIXORD
-      INTEGER           I, I1, IERR, IRANK, J, KB1, KB2, KC1, KC2T,
-     $                  KHSVP, KHSVP2, KR, KT, KTI, KU, KW, KW1, KW2,
-     $                  LDB1, LDB2, LDC1, LDC2T, NA, NDIM, NKR1, NMINR,
-     $                  NR1, NU, WRKOPT
-      DOUBLE PRECISION  ATOL, RTOL, SKP, SKP2, SRRTOL
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH
-      EXTERNAL          DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB04MD, AB09AX, DAXPY, DCOPY, DGELSY, DGEMM,
-     $                  DLACPY, DSWAP, MA02AD, MB01SD, TB01KD, TB01WD,
-     $                  XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         ABS, DBLE, INT, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      DISCR  = LSAME( DICO,   'D' )
-      FIXORD = LSAME( ORDSEL, 'F' )
-C
-C     Check the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -2
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( FIXORD .AND. ( NR.LT.0 .OR. NR.GT.N ) ) THEN
-         INFO = -6
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -10
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -12
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -14
-      ELSE IF( TOL2.GT.ZERO .AND. TOL2.GT.TOL1 ) THEN
-         INFO = -17
-      ELSE IF( LDWORK.LT.MAX( N*( 2*N + MAX( N, M, P ) + 5 ) +
-     $                        ( N*( N + 1 ) )/2,
-     $                        N*( M + P + 2 ) + 2*M*P + MIN( N, M ) +
-     $                        MAX ( 3*M + 1, MIN( N, M ) + P ) ) ) THEN
-         INFO = -20
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09CX', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 ) THEN
-         NR = 0
-         IWORK(1) = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      RTOL   = DBLE( N )*DLAMCH( 'Epsilon' )
-      SRRTOL = SQRT( RTOL )
-C
-C     Allocate working storage.
-C
-      KT  = 1
-      KTI = KT  + N*N
-      KW  = KTI + N*N
-C
-C     Compute a minimal order balanced realization of the given system.
-C     Workspace: need   N*(2*N+MAX(N,M,P)+5) + N*(N+1)/2;
-C                prefer larger.
-C
-      CALL AB09AX( DICO, 'Balanced', 'Automatic', N, M, P, NMINR, A,
-     $             LDA, B, LDB, C, LDC, HSV, DWORK(KT), N, DWORK(KTI),
-     $             N, TOL2, IWORK, DWORK(KW), LDWORK-KW+1, IWARN, INFO )
-C
-      IF( INFO.NE.0 )
-     $   RETURN
-      WRKOPT = INT( DWORK(KW) ) + KW - 1
-C
-C     Compute the order of reduced system.
-C
-      ATOL = RTOL*HSV(1)
-      IF( FIXORD ) THEN
-         IF( NR.GT.0 ) THEN
-            IF( NR.GT.NMINR ) THEN
-               NR = NMINR
-               IWARN = 1
-            ENDIF
-         ENDIF
-      ELSE
-         ATOL = MAX( TOL1, ATOL )
-         NR = 0
-         DO 10 I = 1, NMINR
-            IF( HSV(I).LE.ATOL ) GO TO 20
-            NR = NR + 1
-   10    CONTINUE
-   20    CONTINUE
-      ENDIF
-C
-      IF( NR.EQ.NMINR ) THEN
-         IWORK(1) = NMINR
-         DWORK(1) = WRKOPT
-         KW = N*(N+2)+1
-C
-C        Reduce Ar to a real Schur form.
-C
-         CALL TB01WD( NMINR, M, P, A, LDA, B, LDB, C, LDC,
-     $                DWORK(2*N+1), N, DWORK, DWORK(N+1), DWORK(KW),
-     $                LDWORK-KW+1, IERR )
-         IF( IERR.NE.0 ) THEN
-            INFO = 3
-            RETURN
-         END IF
-         RETURN
-      END IF
-      SKP = HSV(NR+1)
-C
-C     If necessary, reduce the order such that HSV(NR) > HSV(NR+1).
-C
-   30 IF( NR.GT.0 ) THEN
-         IF( ABS( HSV(NR)-SKP ).LE.SRRTOL*SKP ) THEN
-            NR = NR - 1
-            GO TO 30
-         END IF
-      END IF
-C
-C     Determine KR, the multiplicity of HSV(NR+1).
-C
-      KR = 1
-      DO 40 I = NR+2, NMINR
-         IF( ABS( HSV(I)-SKP ).GT.SRRTOL*SKP ) GO TO 50
-         KR = KR + 1
-   40 CONTINUE
-   50 CONTINUE
-C
-C     For discrete-time case, apply the discrete-to-continuous bilinear
-C     transformation.
-C
-      IF( DISCR ) THEN
-C
-C        Workspace: need   N;
-C                   prefer larger.
-C
-         CALL AB04MD( 'Discrete', NMINR, M, P, ONE, ONE, A, LDA, B, LDB,
-     $                C, LDC, D, LDD, IWORK, DWORK, LDWORK, INFO )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) )
-      END IF
-C
-C     Define leading dimensions and offsets for temporary data.
-C
-      NU     = NMINR - NR - KR
-      NA     = NR + NU
-      LDB1   = NA
-      LDC1   = P
-      LDB2   = KR
-      LDC2T  = MAX( KR, M )
-      NR1    = NR  + 1
-      NKR1   = MIN( NMINR, NR1 + KR )
-C
-      KHSVP  = 1
-      KHSVP2 = KHSVP  + NA
-      KU     = KHSVP2 + NA
-      KB1    = KU     + P*M
-      KB2    = KB1    + LDB1*M
-      KC1    = KB2    + LDB2*M
-      KC2T   = KC1    + LDC1*NA
-      KW     = KC2T   + LDC2T*P
-C
-C     Save B2 and C2'.
-C
-      CALL DLACPY( 'Full', KR, M, B(NR1,1), LDB, DWORK(KB2), LDB2 )
-      CALL MA02AD( 'Full', P, KR, C(1,NR1), LDC, DWORK(KC2T), LDC2T )
-      IF( NR.GT.0 ) THEN
-C
-C        Permute the elements of HSV and of matrices A, B, C.
-C
-         CALL DCOPY( NR, HSV(1), 1, DWORK(KHSVP), 1 )
-         CALL DCOPY( NU, HSV(NKR1), 1, DWORK(KHSVP+NR), 1 )
-         CALL DLACPY( 'Full', NMINR, NU, A(1,NKR1), LDA, A(1,NR1), LDA )
-         CALL DLACPY( 'Full', NU, NA, A(NKR1,1), LDA, A(NR1,1), LDA )
-         CALL DLACPY( 'Full', NU, M, B(NKR1,1), LDB, B(NR1,1), LDB )
-         CALL DLACPY( 'Full', P, NU, C(1,NKR1), LDC, C(1,NR1), LDC )
-C
-C        Save B1 and C1.
-C
-         CALL DLACPY( 'Full', NA, M, B, LDB, DWORK(KB1), LDB1 )
-         CALL DLACPY( 'Full', P, NA, C, LDC, DWORK(KC1), LDC1 )
-      END IF
-C
-C     Compute U = C2*pinv(B2').
-C     Workspace: need   N*(M+P+2) + 2*M*P +
-C                       max(min(KR,M)+3*M+1,2*min(KR,M)+P);
-C                prefer N*(M+P+2) + 2*M*P +
-C                       max(min(KR,M)+2*M+(M+1)*NB,2*min(KR,M)+P*NB),
-C                where  NB  is the maximum of the block sizes for
-C                DGEQP3, DTZRZF, DTZRQF, DORMQR, and DORMRZ.
-C
-      DO 55 J = 1, M
-         IWORK(J) = 0
-   55 CONTINUE
-      CALL DGELSY( KR, M, P, DWORK(KB2), LDB2, DWORK(KC2T), LDC2T,
-     $             IWORK, RTOL, IRANK, DWORK(KW), LDWORK-KW+1, IERR )
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      CALL MA02AD( 'Full', M, P, DWORK(KC2T), LDC2T, DWORK(KU), P )
-C
-C     Compute D <- D + HSV(NR+1)*U.
-C
-      I = KU
-      DO 60 J = 1, M
-         CALL DAXPY( P, SKP, DWORK(I), 1, D(1,J), 1 )
-         I = I + P
-   60 CONTINUE
-C
-      IF( NR.GT.0 ) THEN
-         SKP2 = SKP*SKP
-C
-C        Compute G = inv(S1*S1-skp*skp*I), where S1 is the diagonal
-C        matrix of relevant singular values (of order NMINR - KR).
-C
-         I1 = KHSVP2
-         DO 70 I = KHSVP, KHSVP+NA-1
-            DWORK(I1) = ONE / ( DWORK(I)*DWORK(I) - SKP2 )
-            I1 = I1 + 1
-   70    CONTINUE
-C
-C        Compute C <- C1*S1-skp*U*B1'.
-C
-         CALL MB01SD( 'Column', P, NA, C, LDC, DWORK, DWORK(KHSVP) )
-         CALL DGEMM( 'NoTranspose', 'Transpose', P, NA, M, -SKP,
-     $               DWORK(KU), P, DWORK(KB1), LDB1, ONE, C, LDC )
-C
-C        Compute B <- G*(S1*B1-skp*C1'*U).
-C
-         CALL MB01SD( 'Row', NA, M, B, LDB, DWORK(KHSVP), DWORK )
-         CALL DGEMM( 'Transpose', 'NoTranspose', NA, M, P, -SKP,
-     $               DWORK(KC1), LDC1, DWORK(KU), P, ONE, B, LDB )
-         CALL MB01SD( 'Row', NA, M, B, LDB, DWORK(KHSVP2), DWORK )
-C
-C        Compute A <- -A1' - B*B1'.
-C
-         DO 80 J = 2, NA
-            CALL DSWAP( J-1, A(1,J), 1, A(J,1), LDA )
-   80    CONTINUE
-         CALL DGEMM( 'NoTranspose', 'Transpose', NA, NA, M, -ONE, B,
-     $               LDB, DWORK(KB1), LDB1, -ONE, A, LDA )
-C
-C        Extract stable part.
-C        Workspace:  need   N*N+5*N;
-C                    prefer larger.
-C
-         KW1 = NA*NA + 1
-         KW2 = KW1 + NA
-         KW  = KW2 + NA
-         CALL TB01KD( 'Continuous', 'Stability', 'General', NA, M, P,
-     $                ZERO, A, LDA, B, LDB, C, LDC, NDIM, DWORK, NA,
-     $                DWORK(KW1), DWORK(KW2), DWORK(KW), LDWORK-KW+1,
-     $                IERR )
-         IF( IERR.NE.0 ) THEN
-            INFO = 3
-            RETURN
-         END IF
-C
-         IF( NDIM.NE.NR ) THEN
-            INFO = 4
-            RETURN
-         END IF
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C        For discrete-time case, apply the continuous-to-discrete
-C        bilinear transformation.
-C
-         IF( DISCR )
-     $      CALL AB04MD( 'Continuous', NR, M, P, ONE, ONE, A, LDA, B,
-     $                   LDB, C, LDC, D, LDD, IWORK, DWORK, LDWORK,
-     $                   INFO )
-      END IF
-      IWORK(1) = NMINR
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of AB09CX ***
-      END
--- a/extra/control-devel/src/AB09DD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-      SUBROUTINE AB09DD( DICO, N, M, P, NR, A, LDA, B, LDB, C, LDC,
-     $                   D, LDD, RCOND, IWORK, DWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order model by using singular perturbation
-C     approximation formulas.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The dimension of the state vector, i.e. the order of the
-C             matrix A; also the number of rows of matrix B and the
-C             number of columns of the matrix C.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The dimension of input vector, i.e. the number of columns
-C             of matrices B and D.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The dimension of output vector, i.e. the number of rows of
-C             matrices C and D.  P >= 0.
-C
-C     NR      (input) INTEGER
-C             The order of the reduced order system.  N >= NR >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix of the original system.
-C             On exit, the leading NR-by-NR part of this array contains
-C             the state dynamics matrix Ar of the reduced order system.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input/state matrix of the original system.
-C             On exit, the leading NR-by-M part of this array contains
-C             the input/state matrix Br of the reduced order system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the state/output matrix of the original system.
-C             On exit, the leading P-by-NR part of this array contains
-C             the state/output matrix Cr of the reduced order system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the input/output matrix of the original system.
-C             On exit, the leading P-by-M part of this array contains
-C             the input/output matrix Dr of the reduced order system.
-C             If NR = 0 and the given system is stable, then D contains
-C             the steady state gain of the system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     RCOND   (output) DOUBLE PRECISION
-C             The reciprocal condition number of the matrix A22-g*I
-C             (see METHOD).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension 2*(N-NR)
-C
-C     DWORK   DOUBLE PRECISION array, dimension 4*(N-NR)
-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 matrix A22-g*I (see METHOD) is numerically
-C                  singular.
-C
-C     METHOD
-C
-C     Given the system (A,B,C,D), partition the system matrices as
-C
-C            ( A11 A12 )        ( B1 )
-C        A = (         ) ,  B = (    ) ,  C = ( C1  C2 ),
-C            ( A21 A22 )        ( B2 )
-C
-C     where A11 is NR-by-NR, B1 is NR-by-M, C1 is P-by-NR, and the other
-C     submatrices have appropriate dimensions.
-C
-C     The matrices of the reduced order system (Ar,Br,Cr,Dr) are
-C     computed according to the following residualization formulas:
-C                                -1                               -1
-C        Ar = A11 + A12*(g*I-A22)  *A21 ,  Br = B1 + A12*(g*I-A22)  *B2
-C                              -1                               -1
-C        Cr = C1 + C2*(g*I-A22)  *A21   ,  Dr = D + C2*(g*I-A22)  *B2
-C
-C     where g = 0 if DICO = 'C' and g = 1 if DICO = 'D'.
-C
-C     CONTRIBUTOR
-C
-C     C. Oara and A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, March 1998.
-C     Based on the RASP routine SRESID.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Model reduction, multivariable system, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO
-      INTEGER           INFO, LDA, LDB, LDC, LDD, M, N, NR, P
-      DOUBLE PRECISION  RCOND
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*), DWORK(*)
-      INTEGER           IWORK(*)
-C     .. Local Scalars
-      LOGICAL           DISCR
-      INTEGER           I, J, K, NS
-      DOUBLE PRECISION  A22NRM
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH, DLANGE
-      EXTERNAL          DLAMCH, DLANGE, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DGECON, DGEMM, DGETRF, DGETRS, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX
-C     .. Executable Statements ..
-C
-C     Check the input scalar arguments.
-C
-      INFO = 0
-      DISCR = LSAME( DICO, 'D' )
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( NR.LT.0 .OR. NR.GT.N ) THEN
-         INFO = -5
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -11
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -13
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09DD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( NR.EQ.N ) THEN
-         RCOND = ONE
-         RETURN
-      END IF
-C
-      K  = NR + 1
-      NS = N - NR
-C
-C     Compute: T = -A22   if  DICO = 'C' and
-C              T = -A22+I if  DICO = 'D'.
-C
-      DO 20 J = K, N
-         DO 10 I = K, N
-            A(I,J) = -A(I,J)
-   10    CONTINUE
-         IF( DISCR ) A(J,J) = A(J,J) + ONE
-   20 CONTINUE
-C
-C     Compute the LU decomposition of T.
-C
-      A22NRM = DLANGE( '1-norm', NS, NS, A(K,K), LDA, DWORK )
-      CALL DGETRF( NS, NS, A(K,K), LDA, IWORK, INFO )
-      IF( INFO.GT.0 ) THEN
-C
-C        Error return.
-C
-         RCOND = ZERO
-         INFO = 1
-         RETURN
-      END IF
-      CALL DGECON( '1-norm', NS, A(K,K), LDA, A22NRM, RCOND, DWORK,
-     $             IWORK(NS+1), INFO )
-      IF( RCOND.LE.DLAMCH('E') ) THEN
-C
-C        Error return.
-C
-         INFO = 1
-         RETURN
-      END IF
-C
-C     Compute A21 <- INV(T)*A21.
-C
-      CALL DGETRS( 'NoTranspose', NS, NR, A(K,K), LDA, IWORK, A(K,1),
-     $             LDA, INFO )
-C
-C     Compute B2 <- INV(T)*B2.
-C
-      CALL DGETRS( 'NoTranspose', NS, M, A(K,K), LDA, IWORK, B(K,1),
-     $             LDB, INFO )
-C
-C     Compute the residualized systems matrices.
-C     Ar = A11 + A12*INV(T)*A21.
-C
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NR, NR, NS, ONE, A(1,K),
-     $            LDA, A(K,1), LDA, ONE, A, LDA )
-C
-C     Br = B1 + A12*INV(T)*B2.
-C
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NR, M, NS, ONE, A(1,K),
-     $            LDA, B(K,1), LDB, ONE, B, LDB )
-C
-C     Cr = C1 + C2*INV(T)*A21.
-C
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', P, NR, NS, ONE, C(1,K),
-     $            LDC, A(K,1), LDA, ONE, C, LDC )
-C
-C     Dr = D + C2*INV(T)*B2.
-C
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', P, M, NS, ONE, C(1,K),
-     $            LDC, B(K,1), LDB, ONE, D, LDD )
-C
-      RETURN
-C *** Last line of AB09DD ***
-      END
--- a/extra/control-devel/src/AB09HD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,671 +0,0 @@
-      SUBROUTINE AB09HD( DICO, JOB, EQUIL, ORDSEL, N, M, P, NR, ALPHA,
-     $                   BETA, A, LDA, B, LDB, C, LDC, D, LDD, NS, HSV,
-     $                   TOL1, TOL2, IWORK, DWORK, LDWORK, BWORK, IWARN,
-     $                   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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order model (Ar,Br,Cr,Dr) for an original
-C     state-space representation (A,B,C,D) by using the stochastic
-C     balancing approach in conjunction with the square-root or
-C     the balancing-free square-root Balance & Truncate (B&T)
-C     or Singular Perturbation Approximation (SPA) model reduction
-C     methods for the ALPHA-stable part of the system.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     JOB     CHARACTER*1
-C             Specifies the model reduction approach to be used
-C             as follows:
-C             = 'B':  use the square-root Balance & Truncate method;
-C             = 'F':  use the balancing-free square-root
-C                     Balance & Truncate method;
-C             = 'S':  use the square-root Singular Perturbation
-C                     Approximation method;
-C             = 'P':  use the balancing-free square-root
-C                     Singular Perturbation Approximation method.
-C
-C     EQUIL   CHARACTER*1
-C             Specifies whether the user wishes to preliminarily
-C             equilibrate the triplet (A,B,C) as follows:
-C             = 'S':  perform equilibration (scaling);
-C             = 'N':  do not perform equilibration.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting order NR is fixed;
-C             = 'A':  the resulting order NR is automatically determined
-C                     on basis of the given tolerance TOL1.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation,
-C             i.e., the order of the matrix A.  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             P <= M if BETA = 0.
-C
-C     NR      (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NR is the desired order of the
-C             resulting reduced order system.  0 <= NR <= N.
-C             On exit, if INFO = 0, NR is the order of the resulting
-C             reduced order model. For a system with NU ALPHA-unstable
-C             eigenvalues and NS ALPHA-stable eigenvalues (NU+NS = N),
-C             NR is set as follows: if ORDSEL = 'F', NR is equal to
-C             NU+MIN(MAX(0,NR-NU),NMIN), where NR is the desired order
-C             on entry, and NMIN is the order of a minimal realization
-C             of the ALPHA-stable part of the given system; NMIN is
-C             determined as the number of Hankel singular values greater
-C             than NS*EPS, where EPS is the machine precision
-C             (see LAPACK Library Routine DLAMCH);
-C             if ORDSEL = 'A', NR is the sum of NU and the number of
-C             Hankel singular values greater than MAX(TOL1,NS*EPS);
-C             NR can be further reduced to ensure that
-C             HSV(NR-NU) > HSV(NR+1-NU).
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             Specifies the ALPHA-stability boundary for the eigenvalues
-C             of the state dynamics matrix A. For a continuous-time
-C             system (DICO = 'C'), ALPHA <= 0 is the boundary value for
-C             the real parts of eigenvalues, while for a discrete-time
-C             system (DICO = 'D'), 0 <= ALPHA <= 1 represents the
-C             boundary value for the moduli of eigenvalues.
-C             The ALPHA-stability domain does not include the boundary.
-C
-C     BETA    (input) DOUBLE PRECISION
-C             BETA > 0 specifies the absolute/relative error weighting
-C             parameter. A large positive value of BETA favours the
-C             minimization of the absolute approximation error, while a
-C             small value of BETA is appropriate for the minimization
-C             of the relative error.
-C             BETA = 0 means a pure relative error method and can be
-C             used only if rank(D) = P.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A.
-C             On exit, if INFO = 0, the leading NR-by-NR part of this
-C             array contains the state dynamics matrix Ar of the reduced
-C             order system.
-C             The resulting A has a block-diagonal form with two blocks.
-C             For a system with NU ALPHA-unstable eigenvalues and
-C             NS ALPHA-stable eigenvalues (NU+NS = N), the leading
-C             NU-by-NU block contains the unreduced part of A
-C             corresponding to ALPHA-unstable eigenvalues in an
-C             upper real Schur form.
-C             The trailing (NR+NS-N)-by-(NR+NS-N) block contains
-C             the reduced part of A corresponding to ALPHA-stable
-C             eigenvalues.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, if INFO = 0, the leading NR-by-M part of this
-C             array contains the input/state matrix Br of the reduced
-C             order system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, if INFO = 0, the leading P-by-NR part of this
-C             array contains the state/output matrix Cr of the reduced
-C             order system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the original input/output matrix D.
-C             On exit, if INFO = 0, the leading P-by-M part of this
-C             array contains the input/output matrix Dr of the reduced
-C             order system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     NS      (output) INTEGER
-C             The dimension of the ALPHA-stable subsystem.
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, the leading NS elements of HSV contain the
-C             Hankel singular values of the phase system corresponding
-C             to the ALPHA-stable part of the original system.
-C             The Hankel singular values are ordered decreasingly.
-C
-C     Tolerances
-C
-C     TOL1    DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL1 contains the tolerance for
-C             determining the order of reduced system.
-C             For model reduction, the recommended value of TOL1 lies
-C             in the interval [0.00001,0.001].
-C             If TOL1 <= 0 on entry, the used default value is
-C             TOL1 = NS*EPS, where NS is the number of
-C             ALPHA-stable eigenvalues of A and EPS is the machine
-C             precision (see LAPACK Library Routine DLAMCH).
-C             If ORDSEL = 'F', the value of TOL1 is ignored.
-C             TOL1 < 1.
-C
-C     TOL2    DOUBLE PRECISION
-C             The tolerance for determining the order of a minimal
-C             realization of the phase system (see METHOD) corresponding
-C             to the ALPHA-stable part of the given system.
-C             The recommended value is TOL2 = NS*EPS.
-C             This value is used by default if TOL2 <= 0 on entry.
-C             If TOL2 > 0 and ORDSEL = 'A', then TOL2 <= TOL1.
-C             TOL2 < 1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension MAX(1,2*N)
-C             On exit with INFO = 0, IWORK(1) contains the order of the
-C             minimal realization of the system.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK and DWORK(2) contains RCOND, the reciprocal
-C             condition number of the U11 matrix from the expression
-C             used to compute the solution X = U21*inv(U11) of the
-C             Riccati equation for spectral factorization.
-C             A small value RCOND indicates possible ill-conditioning
-C             of the respective Riccati equation.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 2*N*N + MB*(N+P) + MAX( 2, N*(MAX(N,MB,P)+5),
-C                                    2*N*P+MAX(P*(MB+2),10*N*(N+1) ) ),
-C             where MB = M if BETA = 0 and MB = M+P if BETA > 0.
-C             For optimum performance LDWORK should be larger.
-C
-C     BWORK   LOGICAL array, dimension 2*N
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NR is greater
-C                   than NSMIN, the sum of the order of the
-C                   ALPHA-unstable part and the order of a minimal
-C                   realization of the ALPHA-stable part of the given
-C                   system; in this case, the resulting NR is set equal
-C                   to NSMIN;
-C             = 2:  with ORDSEL = 'F', the selected order NR corresponds
-C                   to repeated singular values for the ALPHA-stable
-C                   part, which are neither all included nor all
-C                   excluded from the reduced model; in this case, the
-C                   resulting NR is automatically decreased to exclude
-C                   all repeated singular values;
-C             = 3:  with ORDSEL = 'F', the selected order NR is less
-C                   than the order of the ALPHA-unstable part of the
-C                   given system; in this case NR is set equal to the
-C                   order of the ALPHA-unstable part.
-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 computation of the ordered real Schur form of A
-C                   failed;
-C             = 2:  the reduction of the Hamiltonian matrix to real
-C                   Schur form failed;
-C             = 3:  the reordering of the real Schur form of the
-C                   Hamiltonian matrix failed;
-C             = 4:  the Hamiltonian matrix has less than N stable
-C                   eigenvalues;
-C             = 5:  the coefficient matrix U11 in the linear system
-C                   X*U11 = U21 to determine X is singular to working
-C                   precision;
-C             = 6:  BETA = 0 and D has not a maximal row rank;
-C             = 7:  the computation of Hankel singular values failed;
-C             = 8:  the separation of the ALPHA-stable/unstable diagonal
-C                   blocks failed because of very close eigenvalues;
-C             = 9:  the resulting order of reduced stable part is less
-C                   than the number of unstable zeros of the stable
-C                   part.
-C     METHOD
-C
-C     Let be the following linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t) + Du(t),                      (1)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system. The subroutine AB09HD determines for
-C     the given system (1), the matrices of a reduced order system
-C
-C          d[z(t)] = Ar*z(t) + Br*u(t)
-C          yr(t)   = Cr*z(t) + Dr*u(t),                  (2)
-C
-C     such that
-C
-C          INFNORM[inv(conj(W))*(G-Gr)] <=
-C                       (1+HSV(NR+NS-N+1)) / (1-HSV(NR+NS-N+1)) + ...
-C                       + (1+HSV(NS)) / (1-HSV(NS)) - 1,
-C
-C     where G and Gr are transfer-function matrices of the systems
-C     (A,B,C,D) and (Ar,Br,Cr,Dr), respectively, W is the right, minimum
-C     phase spectral factor satisfying
-C
-C         G1*conj(G1) = conj(W)* W,                      (3)
-C
-C     G1 is the NS-order ALPHA-stable part of G, and INFNORM(G) is the
-C     infinity-norm of G. HSV(1), ... , HSV(NS) are the Hankel-singular
-C     values of the stable part of the phase system (Ap,Bp,Cp)
-C     with the transfer-function matrix
-C
-C          P = inv(conj(W))*G1.
-C
-C     If BETA > 0, then the model reduction is performed on [G BETA*I]
-C     instead of G. This is the recommended approach to be used when D
-C     has not a maximal row rank or when a certain balance between
-C     relative and absolute approximation errors is desired. For
-C     increasingly large values of BETA, the obtained reduced system
-C     assymptotically approaches that computed by using the
-C     Balance & Truncate or Singular Perturbation Approximation methods.
-C
-C     Note: conj(G)  denotes either G'(-s) for a continuous-time system
-C           or G'(1/z) for a discrete-time system.
-C           inv(G) is the inverse of G.
-C
-C     The following procedure is used to reduce a given G:
-C
-C     1) Decompose additively G as
-C
-C          G = G1 + G2,
-C
-C        such that G1 = (As,Bs,Cs,D) has only ALPHA-stable poles and
-C        G2 = (Au,Bu,Cu) has only ALPHA-unstable poles.
-C
-C     2) Determine G1r, a reduced order approximation of the
-C        ALPHA-stable part G1 using the balancing stochastic method
-C        in conjunction with either the B&T [1,2] or SPA methods [3].
-C
-C     3) Assemble the reduced model Gr as
-C
-C           Gr = G1r + G2.
-C
-C     Note: The employed stochastic truncation algorithm [2,3] has the
-C     property that right half plane zeros of G1 remain as right half
-C     plane zeros of G1r. Thus, the order can not be chosen smaller than
-C     the sum of the number of unstable poles of G and the number of
-C     unstable zeros of G1.
-C
-C     The reduction of the ALPHA-stable part G1 is done as follows.
-C
-C     If JOB = 'B', the square-root stochastic Balance & Truncate
-C     method of [1] is used.
-C     For an ALPHA-stable continuous-time system (DICO = 'C'),
-C     the resulting reduced model is stochastically balanced.
-C
-C     If JOB = 'F', the balancing-free square-root version of the
-C     stochastic Balance & Truncate method [1] is used to reduce
-C     the ALPHA-stable part G1.
-C
-C     If JOB = 'S', the stochastic balancing method is used to reduce
-C     the ALPHA-stable part G1, in conjunction with the square-root
-C     version of the Singular Perturbation Approximation method [3,4].
-C
-C     If JOB = 'P', the stochastic balancing method is used to reduce
-C     the ALPHA-stable part G1, in conjunction with the balancing-free
-C     square-root version of the Singular Perturbation Approximation
-C     method [3,4].
-C
-C     REFERENCES
-C
-C     [1] Varga A. and Fasol K.H.
-C         A new square-root balancing-free stochastic truncation model
-C         reduction algorithm.
-C         Proc. 12th IFAC World Congress, Sydney, 1993.
-C
-C     [2] Safonov M. G. and Chiang R. Y.
-C         Model reduction for robust control: a Schur relative error
-C         method.
-C         Int. J. Adapt. Contr. Sign. Proc., vol. 2, pp. 259-272, 1988.
-C
-C     [3] Green M. and Anderson B. D. O.
-C         Generalized balanced stochastic truncation.
-C         Proc. 29-th CDC, Honolulu, Hawaii, pp. 476-481, 1990.
-C
-C     [4] Varga A.
-C         Balancing-free square-root algorithm for computing
-C         singular perturbation approximations.
-C         Proc. 30-th IEEE CDC,  Brighton, Dec. 11-13, 1991,
-C         Vol. 2, pp. 1062-1065.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on accuracy enhancing square-root or
-C     balancing-free square-root techniques. The effectiveness of the
-C     accuracy enhancing technique depends on the accuracy of the
-C     solution of a Riccati equation. An ill-conditioned Riccati
-C     solution typically results when [D BETA*I] is nearly
-C     rank deficient.
-C                                      3
-C     The algorithm requires about 100N  floating point operations.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, May 2000.
-C     D. Sima, University of Bucharest, May 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, May 2000.
-C     Partly based on the RASP routine SRBFS, by A. Varga, 1992.
-C
-C     REVISIONS
-C
-C     A. Varga, Australian National University, Canberra, November 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Dec. 2000.
-C              Oct. 2001.
-C
-C     KEYWORDS
-C
-C     Minimal realization, model reduction, multivariable system,
-C     state-space model, state-space representation,
-C     stochastic balancing.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE, TWO, TWOBY3, C100
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
-     $                    TWOBY3 = TWO/3.0D0, C100 = 100.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, EQUIL, JOB, ORDSEL
-      INTEGER           INFO, IWARN, LDA, LDB, LDC, LDD, LDWORK,
-     $                  M, N, NR, NS, P
-      DOUBLE PRECISION  ALPHA, BETA, TOL1, TOL2
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                  DWORK(*), HSV(*)
-      LOGICAL           BWORK(*)
-C     .. Local Scalars ..
-      LOGICAL           BTA, DISCR, FIXORD, LEQUIL, SPA
-      INTEGER           IERR, IWARNL, KB, KD, KT, KTI, KU, KW, KWI, KWR,
-     $                  LW, LWR, MB, N2, NMR, NN, NRA, NU, NU1, WRKOPT
-      DOUBLE PRECISION  EPSM, MAXRED, RICOND, SCALEC, SCALEO
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH
-      EXTERNAL          DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB04MD, AB09HY, AB09IX, DLACPY, DLASET, TB01ID,
-     $                  TB01KD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         INT, MAX, MIN
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      DISCR  = LSAME( DICO,   'D' )
-      FIXORD = LSAME( ORDSEL, 'F' )
-      LEQUIL = LSAME( EQUIL,  'S' )
-      BTA    = LSAME( JOB,    'B' ) .OR. LSAME( JOB, 'F' )
-      SPA    = LSAME( JOB,    'S' ) .OR. LSAME( JOB, 'P' )
-      MB = M
-      IF( BETA.GT.ZERO ) MB = M + P
-      LW = 2*N*N + MB*(N+P) + MAX( 2, N*(MAX( N, MB, P )+5),
-     $                 2*N*P+MAX( P*(MB+2), 10*N*(N+1) ) )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( BTA .OR. SPA ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( LEQUIL .OR. LSAME( EQUIL, 'N' ) ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( P.LT.0 .OR. ( BETA.EQ.ZERO .AND. P.GT.M ) ) THEN
-         INFO = -7
-      ELSE IF( FIXORD .AND. ( NR.LT.0 .OR. NR.GT.N ) ) THEN
-         INFO = -8
-      ELSE IF( ( DISCR .AND. ( ALPHA.LT.ZERO .OR. ALPHA.GT.ONE ) ) .OR.
-     $    ( .NOT.DISCR .AND.   ALPHA.GT.ZERO ) ) THEN
-         INFO = -9
-      ELSE IF( BETA.LT.ZERO ) THEN
-         INFO = -10
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -12
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -14
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -16
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -18
-      ELSE IF( TOL1.GE.ONE ) THEN
-         INFO = -21
-      ELSE IF( ( TOL2.GT.ZERO .AND. .NOT.FIXORD .AND. TOL2.GT.TOL1 )
-     $         .OR. TOL2.GE.ONE ) THEN
-         INFO = -22
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -25
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09HD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 .OR.
-     $   ( BTA .AND. FIXORD .AND. NR.EQ.0 ) ) THEN
-         NR = 0
-         NS = 0
-         IWORK(1) = 0
-         DWORK(1) = TWO
-         DWORK(2) = ONE
-         RETURN
-      END IF
-C
-      IF( LEQUIL ) THEN
-C
-C        Scale simultaneously the matrices A, B and C:
-C        A <- inv(D)*A*D, B <- inv(D)*B and C <- C*D, where D is a
-C        diagonal matrix.
-C        Workspace: N.
-C
-         MAXRED = C100
-         CALL TB01ID( 'All', N, M, P, MAXRED, A, LDA, B, LDB, C, LDC,
-     $                DWORK, INFO )
-      END IF
-C
-C     Allocate working storage.
-C
-      NN  = N*N
-      KU  = 1
-      KWR = KU + NN
-      KWI = KWR + N
-      KW  = KWI + N
-      LWR = LDWORK - KW + 1
-C
-C     Reduce A to a block-diagonal real Schur form, with the
-C     ALPHA-unstable part in the leading diagonal position, using a
-C     non-orthogonal similarity transformation A <- inv(T)*A*T and
-C     apply the transformation to B and C: B <- inv(T)*B and C <- C*T.
-C
-C     Workspace needed:      N*(N+2);
-C     Additional workspace:  need   3*N;
-C                            prefer larger.
-C
-      CALL TB01KD( DICO, 'Unstable', 'General', N, M, P, ALPHA, A, LDA,
-     $             B, LDB, C, LDC, NU, DWORK(KU), N, DWORK(KWR),
-     $             DWORK(KWI), DWORK(KW), LWR, IERR )
-C
-      IF( IERR.NE.0 ) THEN
-         IF( IERR.NE.3 ) THEN
-            INFO = 1
-         ELSE
-            INFO = 8
-         END IF
-         RETURN
-      END IF
-C
-      WRKOPT = INT( DWORK(KW) ) + KW - 1
-C
-      IWARNL = 0
-      NS = N - NU
-      IF( FIXORD ) THEN
-         NRA = MAX( 0, NR-NU )
-         IF( NR.LT.NU )
-     $      IWARNL = 3
-      ELSE
-         NRA = 0
-      END IF
-C
-C     Finish if the system is completely unstable.
-C
-      IF( NS.EQ.0 ) THEN
-         NR = NU
-         IWORK(1) = NS
-         DWORK(1) = WRKOPT
-         DWORK(2) = ONE
-         RETURN
-      END IF
-C
-      NU1 = NU + 1
-C
-C     Allocate working storage.
-C
-      N2  = N + N
-      KB  = 1
-      KD  = KB  + N*MB
-      KT  = KD  + P*MB
-      KTI = KT  + N*N
-      KW  = KTI + N*N
-C
-C     Form [B 0] and [D BETA*I].
-C
-      CALL DLACPY( 'F', NS, M, B(NU1,1), LDB, DWORK(KB), N )
-      CALL DLACPY( 'F', P, M, D, LDD, DWORK(KD), P )
-      IF( BETA.GT.ZERO ) THEN
-         CALL DLASET( 'F', NS, P, ZERO, ZERO, DWORK(KB+N*M), N )
-         CALL DLASET( 'F', P,  P, ZERO, BETA, DWORK(KD+P*M), P )
-      END IF
-C
-C     For discrete-time case, apply the discrete-to-continuous bilinear
-C     transformation to the stable part.
-C
-      IF( DISCR ) THEN
-C
-C        Real workspace:    need  N, prefer larger;
-C        Integer workspace: need  N.
-C
-         CALL AB04MD( 'Discrete', NS, MB, P, ONE, ONE, A(NU1,NU1), LDA,
-     $                DWORK(KB), N, C(1,NU1), LDC, DWORK(KD), P,
-     $                IWORK, DWORK(KT), LDWORK-KT+1, IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KT) ) + KT - 1 )
-      END IF
-C
-C     Compute in DWORK(KTI) and DWORK(KT) the Cholesky factors S and R
-C     of the controllability and observability Grammians, respectively.
-C     Real workspace:    need  2*N*N + MB*(N+P)+
-C                              MAX( 2, N*(MAX(N,MB,P)+5),
-C                                   2*N*P+MAX(P*(MB+2), 10*N*(N+1) ) );
-C                        prefer larger.
-C     Integer workspace: need  2*N.
-C
-      CALL AB09HY( NS, MB, P, A(NU1,NU1), LDA, DWORK(KB), N,
-     $             C(1,NU1), LDC, DWORK(KD), P, SCALEC, SCALEO,
-     $             DWORK(KTI), N, DWORK(KT), N, IWORK, DWORK(KW),
-     $             LDWORK-KW+1, BWORK, INFO )
-      IF( INFO.NE.0 )
-     $   RETURN
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      RICOND = DWORK(KW+1)
-C
-C     Compute a BTA or SPA of the stable part.
-C     Real workspace:  need  2*N*N + MB*(N+P)+
-C                            MAX( 1, 2*N*N+5*N, N*MAX(MB,P) ).
-C
-      EPSM = DLAMCH( 'Epsilon' )
-      CALL AB09IX( 'C', JOB, 'Schur', ORDSEL, NS, MB, P, NRA, SCALEC,
-     $             SCALEO, A(NU1,NU1), LDA, DWORK(KB), N, C(1,NU1), LDC,
-     $             DWORK(KD), P, DWORK(KTI), N, DWORK(KT), N, NMR, HSV,
-     $             MAX( TOL1, N*EPSM ), TOL2, IWORK, DWORK(KW),
-     $             LDWORK-KW+1, IWARN, IERR )
-      IWARN = MAX( IWARN, IWARNL )
-      IF( IERR.NE.0 ) THEN
-         INFO = 7
-         RETURN
-      END IF
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Check if the resulting order is greater than the number of
-C     unstable zeros (this check is implicit by looking at Hankel
-C     singular values equal to 1).
-C
-      IF( NRA.LT.NS .AND. HSV(NRA+1).GE.ONE-EPSM**TWOBY3 ) THEN
-         INFO = 9
-         RETURN
-      END IF
-C
-C     For discrete-time case, apply the continuous-to-discrete
-C     bilinear transformation.
-C
-      IF( DISCR ) THEN
-         CALL AB04MD( 'Continuous', NRA, MB, P, ONE, ONE,
-     $                A(NU1,NU1), LDA, DWORK(KB), N, C(1,NU1), LDC,
-     $                DWORK(KD), P, IWORK, DWORK, LDWORK, IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) )
-      END IF
-C
-      CALL DLACPY( 'F', NRA, M, DWORK(KB), N, B(NU1,1), LDB )
-      CALL DLACPY( 'F', P, M, DWORK(KD), P, D, LDD )
-C
-      NR = NRA + NU
-C
-      IWORK(1) = NMR
-      DWORK(1) = WRKOPT
-      DWORK(2) = RICOND
-C
-      RETURN
-C *** Last line of AB09HD ***
-      END
--- a/extra/control-devel/src/AB09HY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,396 +0,0 @@
-      SUBROUTINE AB09HY( N, M, P, A, LDA, B, LDB, C, LDC, D, LDD,
-     $                   SCALEC, SCALEO, S, LDS, R, LDR, IWORK,
-     $                   DWORK, LDWORK, BWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the Cholesky factors Su and Ru of the controllability
-C     Grammian P = Su*Su' and observability Grammian Q = Ru'*Ru,
-C     respectively, satisfying
-C
-C            A*P  + P*A' +  scalec^2*B*B'   = 0,       (1)
-C
-C            A'*Q + Q*A  +  scaleo^2*Cw'*Cw = 0,       (2)
-C
-C     where
-C            Cw = Hw - Bw'*X,
-C            Hw = inv(Dw)*C,
-C            Bw = (B*D' + P*C')*inv(Dw'),
-C            D*D' = Dw*Dw' (Dw upper triangular),
-C
-C     and, with Aw = A - Bw*Hw, X is the stabilizing solution of the
-C     Riccati equation
-C
-C            Aw'*X + X*Aw + Hw'*Hw + X*Bw*Bw'*X = 0.   (3)
-C
-C     The P-by-M matrix D must have full row rank. Matrix A must be
-C     stable and in a real Schur form.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of state-space representation, i.e.,
-C             the order of the matrix A.  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.  M >= P >= 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             stable state dynamics matrix A in a real Schur canonical
-C             form.
-C
-C     LDA     INTEGER
-C             The leading dimension of 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             input/state matrix B, corresponding to the Schur matrix A.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input) DOUBLE PRECISION array, dimension (LDC,N)
-C             The leading P-by-N part of this array must contain the
-C             state/output matrix C, corresponding to the Schur
-C             matrix A.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input) DOUBLE PRECISION array, dimension (LDD,M)
-C             The leading P-by-M part of this array must
-C             contain the full row rank input/output matrix D.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     SCALEC  (output) DOUBLE PRECISION
-C             Scaling factor for the controllability Grammian in (1).
-C
-C     SCALEO  (output) DOUBLE PRECISION
-C             Scaling factor for the observability Grammian in (2).
-C
-C     S       (output) DOUBLE PRECISION array, dimension (LDS,N)
-C             The leading N-by-N upper triangular part of this array
-C             contains the Cholesky factor Su of the cotrollability
-C             Grammian P = Su*Su' satisfying (1).
-C
-C     LDS     INTEGER
-C             The leading dimension of array S.  LDS >= MAX(1,N).
-C
-C     R       (output) DOUBLE PRECISION array, dimension (LDR,N)
-C             The leading N-by-N upper triangular part of this array
-C             contains the Cholesky factor Ru of the observability
-C             Grammian Q = Ru'*Ru satisfying (2).
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,N).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension 2*N
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK and DWORK(2) contains RCOND, the reciprocal
-C             condition number of the U11 matrix from the expression
-C             used to compute X = U21*inv(U11). A small value RCOND
-C             indicates possible ill-conditioning of the Riccati
-C             equation (3).
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX( 2, N*(MAX(N,M,P)+5),
-C                            2*N*P+MAX(P*(M+2),10*N*(N+1) ) ).
-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:  the state matrix A is not stable or is not in a
-C                   real Schur form;
-C             = 2:  the reduction of Hamiltonian matrix to real Schur
-C                   form failed;
-C             = 3:  the reordering of the real Schur form of the
-C                   Hamiltonian matrix failed;
-C             = 4:  the Hamiltonian matrix has less than N stable
-C                   eigenvalues;
-C             = 5:  the coefficient matrix U11 in the linear system
-C                   X*U11 = U21, used to determine X, is singular to
-C                   working precision;
-C             = 6:  the feedthrough matrix D has not a full row rank P.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, May 2000.
-C     D. Sima, University of Bucharest, May 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, May 2000.
-C     Based on the RASP routines SRGRO and SRGRO1, by A. Varga, 1992.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2001.
-C
-C     KEYWORDS
-C
-C     Minimal realization, model reduction, multivariable system,
-C     state-space model, state-space representation,
-C     stochastic balancing.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION ZERO, ONE, TWO
-      PARAMETER        ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER          INFO, LDA, LDB, LDC, LDD, LDR, LDS, LDWORK, M, N,
-     $                 P
-      DOUBLE PRECISION SCALEC, SCALEO
-C     .. Array Arguments ..
-      INTEGER          IWORK(*)
-      DOUBLE PRECISION A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                 DWORK(*), R(LDR,*), S(LDS,*)
-      LOGICAL          BWORK(*)
-C     .. Local Scalars ..
-      INTEGER          I, IERR, KBW, KCW, KD, KDW, KG, KQ, KS, KTAU, KU,
-     $                 KW, KWI, KWR, LW, N2, WRKOPT
-      DOUBLE PRECISION RCOND, RTOL
-C     .. External Functions ..
-      DOUBLE PRECISION DLANGE, DLAMCH
-      EXTERNAL         DLANGE, DLAMCH
-C     .. External Subroutines ..
-      EXTERNAL         DGEMM, DGERQF, DLACPY, DORGRQ, DSYRK, DTRMM,
-     $                 DTRSM, SB02MD, SB03OU, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC        ABS, DBLE, INT, MAX, MIN
-C     .. Executable Statements ..
-C
-      INFO = 0
-      LW   = MAX( 2, N*( MAX( N, M, P ) + 5 ),
-     $            2*N*P + MAX( P*(M + 2), 10*N*(N + 1) ) )
-C
-      IF( N.LT.0 ) THEN
-         INFO = -1
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( P.LT.0 .OR. P.GT.M ) 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, P ) ) THEN
-         INFO = -9
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -11
-      ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
-         INFO = -15
-      ELSE IF( LDR.LT.MAX( 1, N ) ) THEN
-         INFO = -17
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -20
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09HY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      SCALEC = ONE
-      SCALEO = ONE
-      IF( MIN( N, M, P ).EQ.0 ) THEN
-         DWORK(1) = TWO
-         DWORK(2) = ONE
-         RETURN
-      END IF
-C
-C     Solve for Su the Lyapunov equation
-C                                      2
-C     A*(Su*Su') + (Su*Su')*A' + scalec *B*B' = 0 .
-C
-C     Workspace:  need   N*(MAX(N,M) + 5);
-C                 prefer larger.
-C
-      KU   = 1
-      KTAU = KU + N*MAX( N, M )
-      KW   = KTAU + N
-C
-      CALL DLACPY( 'Full', N, M, B, LDB, DWORK(KU), N )
-      CALL SB03OU( .FALSE., .TRUE., N, M, A, LDA, DWORK(KU), N,
-     $             DWORK(KTAU), S, LDS, SCALEC, DWORK(KW),
-     $             LDWORK - KW + 1, IERR )
-      IF( IERR.NE.0 ) THEN
-         INFO = 1
-         RETURN
-      ENDIF
-      WRKOPT = INT( DWORK(KW) ) + KW - 1
-C
-C     Allocate workspace for Bw' (P*N), Cw (P*N), Q2 (P*M),
-C     where Q2 = inv(Dw)*D.
-C     Workspace:  need   2*N*P + P*M.
-C
-      KBW  = 1
-      KCW  = KBW  + P*N
-      KD   = KCW  + P*N
-      KDW  = KD   + P*(M - P)
-      KTAU = KD   + P*M
-      KW   = KTAU + P
-C
-C     Compute an upper-triangular Dw such that D*D' = Dw*Dw', using
-C     the RQ-decomposition of D: D = [0 Dw]*( Q1 ).
-C                                           ( Q2 )
-C     Additional workspace:  need 2*P; prefer P + P*NB.
-C
-      CALL DLACPY( 'F', P, M, D, LDD, DWORK(KD), P )
-      CALL DGERQF( P, M, DWORK(KD), P, DWORK(KTAU), DWORK(KW),
-     $             LDWORK-KW+1, IERR )
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Check the full row rank of D.
-C
-      RTOL = DBLE( M ) * DLAMCH( 'E' ) *
-     $       DLANGE( '1', P, M, D, LDD, DWORK )
-      DO 10 I = KDW, KDW+P*P-1, P+1
-         IF( ABS( DWORK(I) ).LE.RTOL ) THEN
-            INFO = 6
-            RETURN
-         END IF
-   10 CONTINUE
-C                    -1
-C     Compute Hw = Dw  *C.
-C
-      CALL DLACPY( 'F', P, N, C, LDC, DWORK(KCW), P )
-      CALL DTRSM( 'Left', 'Upper', 'No-transpose', 'Non-unit', P, N,
-     $            ONE, DWORK(KDW), P, DWORK(KCW), P )
-C
-C     Compute Bw' = inv(Dw)*(D*B' + C*Su*Su').
-C
-C     Compute first Hw*Su*Su' in Bw'.
-C
-      CALL DLACPY( 'F', P, N, DWORK(KCW), P, DWORK(KBW), P )
-      CALL DTRMM( 'Right', 'Upper', 'No-transpose', 'Non-unit', P, N,
-     $            ONE, S, LDS, DWORK(KBW), P )
-      CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Non-unit', P, N,
-     $            ONE, S, LDS, DWORK(KBW), P )
-C
-C     Compute Q2 = inv(Dw)*D, as the last P lines of the orthogonal
-C     matrix ( Q1 ) from the RQ decomposition of D.
-C            ( Q2 )
-C     Additional workspace:  need P; prefer P*NB.
-C
-      CALL DORGRQ( P, M, P, DWORK(KD), P, DWORK(KTAU), DWORK(KW),
-     $             LDWORK-KW+1, IERR )
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Compute Bw' <- Bw' + Q2*B'.
-C
-      CALL DGEMM( 'No-transpose', 'Transpose', P, N, M, ONE,
-     $            DWORK(KD), P, B, LDB, ONE, DWORK(KBW), P )
-C
-C     Compute Aw = A - Bw*Hw in R.
-C
-      CALL DLACPY( 'F', N, N, A, LDA, R, LDR )
-      CALL DGEMM( 'Transpose', 'No-transpose', N, N, P, -ONE,
-     $            DWORK(KBW), P, DWORK(KCW), P, ONE, R, LDR )
-C
-C     Allocate storage to solve the Riccati equation (3) for
-C     G(N*N), Q(N*N), WR(2N), WI(2N), S(2N*2N), U(2N*2N).
-C
-      N2  = N + N
-      KG  = KD
-      KQ  = KG  + N*N
-      KWR = KQ  + N*N
-      KWI = KWR + N2
-      KS  = KWI + N2
-      KU  = KS  + N2*N2
-      KW  = KU  + N2*N2
-C
-C     Compute G = -Bw*Bw'.
-C
-      CALL DSYRK( 'Upper', 'Transpose', N, P, -ONE, DWORK(KBW), P, ZERO,
-     $            DWORK(KG), N )
-C
-C     Compute Q = Hw'*Hw.
-C
-      CALL DSYRK( 'Upper', 'Transpose', N, P, ONE, DWORK(KCW), P, ZERO,
-     $            DWORK(KQ), N )
-C
-C     Solve
-C
-C        Aw'*X + X*Aw + Q - X*G*X = 0,
-C
-C     with Q =  Hw'*Hw  and  G = -Bw*Bw'.
-C     Additional workspace: need   6*N;
-C                           prefer larger.
-C
-      CALL SB02MD( 'Continuous', 'None', 'Upper', 'General', 'Stable',
-     $             N, R, LDR, DWORK(KG), N, DWORK(KQ), N, RCOND,
-     $             DWORK(KWR), DWORK(KWI), DWORK(KS), N2,
-     $             DWORK(KU), N2, IWORK, DWORK(KW), LDWORK-KW+1,
-     $             BWORK, INFO )
-      IF( INFO.NE.0 )
-     $   RETURN
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Compute Cw = Hw - Bw'*X.
-C
-      CALL DGEMM ( 'No-transpose', 'No-transpose', P, N, N, -ONE,
-     $              DWORK(KBW), P, DWORK(KQ), N, ONE, DWORK(KCW), P )
-C
-C     Solve for Ru the Lyapunov equation
-C                                      2
-C     A'*(Ru'*Ru) + (Ru'*Ru)*A + scaleo  * Cw'*Cw = 0 .
-C
-C     Workspace:  need   N*(MAX(N,P) + 5);
-C                 prefer larger.
-C
-      KTAU = KCW  + N*MAX( N, P )
-      KW   = KTAU + N
-C
-      CALL SB03OU( .FALSE., .FALSE., N, P, A, LDA, DWORK(KCW), P,
-     $             DWORK(KTAU), R, LDR, SCALEO, DWORK(KW),
-     $             LDWORK - KW + 1, IERR )
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Save optimal workspace and RCOND.
-C
-      DWORK(1) = WRKOPT
-      DWORK(2) = RCOND
-C
-      RETURN
-C *** Last line of AB09HY ***
-      END
--- a/extra/control-devel/src/AB09ID.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1048 +0,0 @@
-      SUBROUTINE AB09ID( DICO, JOBC, JOBO, JOB, WEIGHT, EQUIL, ORDSEL,
-     $                   N, M, P, NV, PV, NW, MW, NR, ALPHA, ALPHAC,
-     $                   ALPHAO, A, LDA, B, LDB, C, LDC, D, LDD,
-     $                   AV, LDAV, BV, LDBV, CV, LDCV, DV, LDDV,
-     $                   AW, LDAW, BW, LDBW, CW, LDCW, DW, LDDW,
-     $                   NS, HSV, TOL1, TOL2, IWORK, DWORK, LDWORK,
-     $                   IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order model (Ar,Br,Cr,Dr) for an original
-C     state-space representation (A,B,C,D) by using the frequency
-C     weighted square-root or balancing-free square-root
-C     Balance & Truncate (B&T) or Singular Perturbation Approximation
-C     (SPA) model reduction methods. The algorithm tries to minimize
-C     the norm of the frequency-weighted error
-C
-C           ||V*(G-Gr)*W||
-C
-C     where G and Gr are the transfer-function matrices of the original
-C     and reduced order models, respectively, and V and W are
-C     frequency-weighting transfer-function matrices. V and W must not
-C     have poles on the imaginary axis for a continuous-time
-C     system or on the unit circle for a discrete-time system.
-C     If G is unstable, only the ALPHA-stable part of G is reduced.
-C     In case of possible pole-zero cancellations in V*G and/or G*W,
-C     the absolute values of parameters ALPHAO and/or ALPHAC must be
-C     different from 1.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     JOBC    CHARACTER*1
-C             Specifies the choice of frequency-weighted controllability
-C             Grammian as follows:
-C             = 'S': choice corresponding to a combination method [4]
-C                    of the approaches of Enns [1] and Lin-Chiu [2,3];
-C             = 'E': choice corresponding to the stability enhanced
-C                    modified combination method of [4].
-C
-C     JOBO    CHARACTER*1
-C             Specifies the choice of frequency-weighted observability
-C             Grammian as follows:
-C             = 'S': choice corresponding to a combination method [4]
-C                    of the approaches of Enns [1] and Lin-Chiu [2,3];
-C             = 'E': choice corresponding to the stability enhanced
-C                    modified combination method of [4].
-C
-C     JOB     CHARACTER*1
-C             Specifies the model reduction approach to be used
-C             as follows:
-C             = 'B':  use the square-root Balance & Truncate method;
-C             = 'F':  use the balancing-free square-root
-C                     Balance & Truncate method;
-C             = 'S':  use the square-root Singular Perturbation
-C                     Approximation method;
-C             = 'P':  use the balancing-free square-root
-C                     Singular Perturbation Approximation method.
-C
-C     WEIGHT  CHARACTER*1
-C             Specifies the type of frequency weighting, as follows:
-C             = 'N':  no weightings are used (V = I, W = I);
-C             = 'L':  only left weighting V is used (W = I);
-C             = 'R':  only right weighting W is used (V = I);
-C             = 'B':  both left and right weightings V and W are used.
-C
-C     EQUIL   CHARACTER*1
-C             Specifies whether the user wishes to preliminarily
-C             equilibrate the triplet (A,B,C) as follows:
-C             = 'S':  perform equilibration (scaling);
-C             = 'N':  do not perform equilibration.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting order NR is fixed;
-C             = 'A':  the resulting order NR is automatically determined
-C                     on basis of the given tolerance TOL1.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation,
-C             i.e., the order of the matrix A.  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     NV      (input) INTEGER
-C             The order of the matrix AV. Also the number of rows of
-C             the matrix BV and the number of columns of the matrix CV.
-C             NV represents the dimension of the state vector of the
-C             system with the transfer-function matrix V.  NV >= 0.
-C
-C     PV      (input) INTEGER
-C             The number of rows of the matrices CV and DV.  PV >= 0.
-C             PV represents the dimension of the output vector of the
-C             system with the transfer-function matrix V.
-C
-C     NW      (input) INTEGER
-C             The order of the matrix AW. Also the number of rows of
-C             the matrix BW and the number of columns of the matrix CW.
-C             NW represents the dimension of the state vector of the
-C             system with the transfer-function matrix W.  NW >= 0.
-C
-C     MW      (input) INTEGER
-C             The number of columns of the matrices BW and DW.  MW >= 0.
-C             MW represents the dimension of the input vector of the
-C             system with the transfer-function matrix W.
-C
-C     NR      (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NR is the desired order of the
-C             resulting reduced order system.  0 <= NR <= N.
-C             On exit, if INFO = 0, NR is the order of the resulting
-C             reduced order model. For a system with NU ALPHA-unstable
-C             eigenvalues and NS ALPHA-stable eigenvalues (NU+NS = N),
-C             NR is set as follows: if ORDSEL = 'F', NR is equal to
-C             NU+MIN(MAX(0,NR-NU),NMIN), where NR is the desired order
-C             on entry, NMIN is the number of frequency-weighted Hankel
-C             singular values greater than NS*EPS*S1, EPS is the
-C             machine precision (see LAPACK Library Routine DLAMCH)
-C             and S1 is the largest Hankel singular value (computed
-C             in HSV(1)); NR can be further reduced to ensure
-C             HSV(NR-NU) > HSV(NR+1-NU);
-C             if ORDSEL = 'A', NR is the sum of NU and the number of
-C             Hankel singular values greater than MAX(TOL1,NS*EPS*S1).
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             Specifies the ALPHA-stability boundary for the eigenvalues
-C             of the state dynamics matrix A. For a continuous-time
-C             system (DICO = 'C'), ALPHA <= 0 is the boundary value for
-C             the real parts of eigenvalues, while for a discrete-time
-C             system (DICO = 'D'), 0 <= ALPHA <= 1 represents the
-C             boundary value for the moduli of eigenvalues.
-C             The ALPHA-stability domain does not include the boundary.
-C
-C     ALPHAC  (input) DOUBLE PRECISION
-C             Combination method parameter for defining the
-C             frequency-weighted controllability Grammian (see METHOD);
-C             ABS(ALPHAC) <= 1.
-C
-C     ALPHAO  (input) DOUBLE PRECISION
-C             Combination method parameter for defining the
-C             frequency-weighted observability Grammian (see METHOD);
-C             ABS(ALPHAO) <= 1.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A.
-C             On exit, if INFO = 0, the leading NR-by-NR part of this
-C             array contains the state dynamics matrix Ar of the
-C             reduced order system.
-C             The resulting A has a block-diagonal form with two blocks.
-C             For a system with NU ALPHA-unstable eigenvalues and
-C             NS ALPHA-stable eigenvalues (NU+NS = N), the leading
-C             NU-by-NU block contains the unreduced part of A
-C             corresponding to ALPHA-unstable eigenvalues.
-C             The trailing (NR+NS-N)-by-(NR+NS-N) block contains
-C             the reduced part of A corresponding to ALPHA-stable
-C             eigenvalues.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, if INFO = 0, the leading NR-by-M part of this
-C             array contains the input/state matrix Br of the reduced
-C             order system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, if INFO = 0, the leading P-by-NR part of this
-C             array contains the state/output matrix Cr of the reduced
-C             order system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the original input/output matrix D.
-C             On exit, if INFO = 0, the leading P-by-M part of this
-C             array contains the input/output matrix Dr of the reduced
-C             order system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     AV      (input/output) DOUBLE PRECISION array, dimension (LDAV,NV)
-C             On entry, if WEIGHT = 'L' or 'B', the leading NV-by-NV
-C             part of this array must contain the state matrix AV of
-C             the system with the transfer-function matrix V.
-C             On exit, if WEIGHT = 'L' or 'B', MIN(N,M,P) > 0 and
-C             INFO = 0, the leading NVR-by-NVR part of this array
-C             contains the state matrix of a minimal realization of V
-C             in a real Schur form. NVR is returned in IWORK(2).
-C             AV is not referenced if WEIGHT = 'R' or 'N',
-C             or MIN(N,M,P) = 0.
-C
-C     LDAV    INTEGER
-C             The leading dimension of array AV.
-C             LDAV >= MAX(1,NV), if WEIGHT = 'L' or 'B';
-C             LDAV >= 1,         if WEIGHT = 'R' or 'N'.
-C
-C     BV      (input/output) DOUBLE PRECISION array, dimension (LDBV,P)
-C             On entry, if WEIGHT = 'L' or 'B', the leading NV-by-P part
-C             of this array must contain the input matrix BV of the
-C             system with the transfer-function matrix V.
-C             On exit, if WEIGHT = 'L' or 'B', MIN(N,M,P) > 0 and
-C             INFO = 0, the leading NVR-by-P part of this array contains
-C             the input matrix of a minimal realization of V.
-C             BV is not referenced if WEIGHT = 'R' or 'N',
-C             or MIN(N,M,P) = 0.
-C
-C     LDBV    INTEGER
-C             The leading dimension of array BV.
-C             LDBV >= MAX(1,NV), if WEIGHT = 'L' or 'B';
-C             LDBV >= 1,         if WEIGHT = 'R' or 'N'.
-C
-C     CV      (input/output) DOUBLE PRECISION array, dimension (LDCV,NV)
-C             On entry, if WEIGHT = 'L' or 'B', the leading PV-by-NV
-C             part of this array must contain the output matrix CV of
-C             the system with the transfer-function matrix V.
-C             On exit, if WEIGHT = 'L' or 'B', MIN(N,M,P) > 0 and
-C             INFO = 0, the leading PV-by-NVR part of this array
-C             contains the output matrix of a minimal realization of V.
-C             CV is not referenced if WEIGHT = 'R' or 'N',
-C             or MIN(N,M,P) = 0.
-C
-C     LDCV    INTEGER
-C             The leading dimension of array CV.
-C             LDCV >= MAX(1,PV), if WEIGHT = 'L' or 'B';
-C             LDCV >= 1,         if WEIGHT = 'R' or 'N'.
-C
-C     DV      (input) DOUBLE PRECISION array, dimension (LDDV,P)
-C             If WEIGHT = 'L' or 'B', the leading PV-by-P part of this
-C             array must contain the feedthrough matrix DV of the system
-C             with the transfer-function matrix V.
-C             DV is not referenced if WEIGHT = 'R' or 'N',
-C             or MIN(N,M,P) = 0.
-C
-C     LDDV    INTEGER
-C             The leading dimension of array DV.
-C             LDDV >= MAX(1,PV), if WEIGHT = 'L' or 'B';
-C             LDDV >= 1,         if WEIGHT = 'R' or 'N'.
-C
-C     AW      (input/output) DOUBLE PRECISION array, dimension (LDAW,NW)
-C             On entry, if WEIGHT = 'R' or 'B', the leading NW-by-NW
-C             part of this array must contain the state matrix AW of
-C             the system with the transfer-function matrix W.
-C             On exit, if WEIGHT = 'R' or 'B', MIN(N,M,P) > 0 and
-C             INFO = 0, the leading NWR-by-NWR part of this array
-C             contains the state matrix of a minimal realization of W
-C             in a real Schur form. NWR is returned in IWORK(3).
-C             AW is not referenced if WEIGHT = 'L' or 'N',
-C             or MIN(N,M,P) = 0.
-C
-C     LDAW    INTEGER
-C             The leading dimension of array AW.
-C             LDAW >= MAX(1,NW), if WEIGHT = 'R' or 'B';
-C             LDAW >= 1,         if WEIGHT = 'L' or 'N'.
-C
-C     BW      (input/output) DOUBLE PRECISION array, dimension (LDBW,MW)
-C             On entry, if WEIGHT = 'R' or 'B', the leading NW-by-MW
-C             part of this array must contain the input matrix BW of the
-C             system with the transfer-function matrix W.
-C             On exit, if WEIGHT = 'R' or 'B', MIN(N,M,P) > 0 and
-C             INFO = 0, the leading NWR-by-MW part of this array
-C             contains the input matrix of a minimal realization of W.
-C             BW is not referenced if WEIGHT = 'L' or 'N',
-C             or MIN(N,M,P) = 0.
-C
-C     LDBW    INTEGER
-C             The leading dimension of array BW.
-C             LDBW >= MAX(1,NW), if WEIGHT = 'R' or 'B';
-C             LDBW >= 1,         if WEIGHT = 'L' or 'N'.
-C
-C     CW      (input/output) DOUBLE PRECISION array, dimension (LDCW,NW)
-C             On entry, if WEIGHT = 'R' or 'B', the leading M-by-NW part
-C             of this array must contain the output matrix CW of the
-C             system with the transfer-function matrix W.
-C             On exit, if WEIGHT = 'R' or 'B', MIN(N,M,P) > 0 and
-C             INFO = 0, the leading M-by-NWR part of this array contains
-C             the output matrix of a minimal realization of W.
-C             CW is not referenced if WEIGHT = 'L' or 'N',
-C             or MIN(N,M,P) = 0.
-C
-C     LDCW    INTEGER
-C             The leading dimension of array CW.
-C             LDCW >= MAX(1,M), if WEIGHT = 'R' or 'B';
-C             LDCW >= 1,        if WEIGHT = 'L' or 'N'.
-C
-C     DW      (input) DOUBLE PRECISION array, dimension (LDDW,MW)
-C             If WEIGHT = 'R' or 'B', the leading M-by-MW part of this
-C             array must contain the feedthrough matrix DW of the system
-C             with the transfer-function matrix W.
-C             DW is not referenced if WEIGHT = 'L' or 'N',
-C             or MIN(N,M,P) = 0.
-C
-C     LDDW    INTEGER
-C             The leading dimension of array DW.
-C             LDDW >= MAX(1,M), if WEIGHT = 'R' or 'B';
-C             LDDW >= 1,        if WEIGHT = 'L' or 'N'.
-C
-C     NS      (output) INTEGER
-C             The dimension of the ALPHA-stable subsystem.
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, the leading NS elements of this array contain
-C             the frequency-weighted Hankel singular values, ordered
-C             decreasingly, of the ALPHA-stable part of the original
-C             system.
-C
-C     Tolerances
-C
-C     TOL1    DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL1 contains the tolerance for
-C             determining the order of reduced system.
-C             For model reduction, the recommended value is
-C             TOL1 = c*S1, where c is a constant in the
-C             interval [0.00001,0.001], and S1 is the largest
-C             frequency-weighted Hankel singular value of the
-C             ALPHA-stable part of the original system (computed
-C             in HSV(1)).
-C             If TOL1 <= 0 on entry, the used default value is
-C             TOL1 = NS*EPS*S1, where NS is the number of
-C             ALPHA-stable eigenvalues of A and EPS is the machine
-C             precision (see LAPACK Library Routine DLAMCH).
-C             If ORDSEL = 'F', the value of TOL1 is ignored.
-C
-C     TOL2    DOUBLE PRECISION
-C             The tolerance for determining the order of a minimal
-C             realization of the ALPHA-stable part of the given system.
-C             The recommended value is TOL2 = NS*EPS*S1.
-C             This value is used by default if TOL2 <= 0 on entry.
-C             If TOL2 > 0 and ORDSEL = 'A', then TOL2 <= TOL1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension
-C             ( MAX( 3, LIWRK1, LIWRK2, LIWRK3 ) ), where
-C             LIWRK1 = 0,             if JOB = 'B';
-C             LIWRK1 = N,             if JOB = 'F';
-C             LIWRK1 = 2*N,           if JOB = 'S' or 'P';
-C             LIWRK2 = 0,             if WEIGHT = 'R' or 'N' or  NV = 0;
-C             LIWRK2 = NV+MAX(P,PV),  if WEIGHT = 'L' or 'B' and NV > 0;
-C             LIWRK3 = 0,             if WEIGHT = 'L' or 'N' or  NW = 0;
-C             LIWRK3 = NW+MAX(M,MW),  if WEIGHT = 'R' or 'B' and NW > 0.
-C             On exit, if INFO = 0, IWORK(1) contains the order of a
-C             minimal realization of the stable part of the system,
-C             IWORK(2) and IWORK(3) contain the actual orders
-C             of the state space realizations of V and W, respectively.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX( LMINL, LMINR, LRCF,
-C                            2*N*N + MAX( 1, LLEFT, LRIGHT, 2*N*N+5*N,
-C                                         N*MAX(M,P) ) ),
-C             where
-C             LMINL  = 0, if WEIGHT = 'R' or 'N' or NV = 0; otherwise,
-C             LMINL  = MAX(LLCF,NV+MAX(NV,3*P))           if P =  PV;
-C             LMINL  = MAX(P,PV)*(2*NV+MAX(P,PV))+
-C                      MAX(LLCF,NV+MAX(NV,3*P,3*PV))      if P <> PV;
-C             LRCF   = 0, and
-C             LMINR  = 0, if WEIGHT = 'L' or 'N' or NW = 0; otherwise,
-C             LMINR  = NW+MAX(NW,3*M)                     if M =  MW;
-C             LMINR  = 2*NW*MAX(M,MW)+NW+MAX(NW,3*M,3*MW) if M <> MW;
-C             LLCF   = PV*(NV+PV)+PV*NV+MAX(NV*(NV+5), PV*(PV+2),
-C                                           4*PV, 4*P);
-C             LRCF   = MW*(NW+MW)+MAX(NW*(NW+5),MW*(MW+2),4*MW,4*M)
-C             LLEFT  = (N+NV)*(N+NV+MAX(N+NV,PV)+5)
-C                              if WEIGHT = 'L' or 'B' and PV > 0;
-C             LLEFT  = N*(P+5) if WEIGHT = 'R' or 'N' or  PV = 0;
-C             LRIGHT = (N+NW)*(N+NW+MAX(N+NW,MW)+5)
-C                              if WEIGHT = 'R' or 'B' and MW > 0;
-C             LRIGHT = N*(M+5) if WEIGHT = 'L' or 'N' or  MW = 0.
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NR is greater
-C                   than NSMIN, the sum of the order of the
-C                   ALPHA-unstable part and the order of a minimal
-C                   realization of the ALPHA-stable part of the given
-C                   system; in this case, the resulting NR is set equal
-C                   to NSMIN;
-C             = 2:  with ORDSEL = 'F', the selected order NR corresponds
-C                   to repeated singular values for the ALPHA-stable
-C                   part, which are neither all included nor all
-C                   excluded from the reduced model; in this case, the
-C                   resulting NR is automatically decreased to exclude
-C                   all repeated singular values;
-C             = 3:  with ORDSEL = 'F', the selected order NR is less
-C                   than the order of the ALPHA-unstable part of the
-C                   given system; in this case NR is set equal to the
-C                   order of the ALPHA-unstable part.
-C             = 10+K:  K violations of the numerical stability condition
-C                   occured during the assignment of eigenvalues in the
-C                   SLICOT Library routines SB08CD and/or SB08DD.
-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 computation of the ordered real Schur form of A
-C                   failed;
-C             = 2:  the separation of the ALPHA-stable/unstable
-C                   diagonal blocks failed because of very close
-C                   eigenvalues;
-C             = 3:  the reduction to a real Schur form of the state
-C                   matrix of a minimal realization of V failed;
-C             = 4:  a failure was detected during the ordering of the
-C                   real Schur form of the state matrix of a minimal
-C                   realization of V or in the iterative process to
-C                   compute a left coprime factorization with inner
-C                   denominator;
-C             = 5:  if DICO = 'C' and the matrix AV has an observable
-C                   eigenvalue on the imaginary axis, or DICO = 'D' and
-C                   AV has an observable eigenvalue on the unit circle;
-C             = 6:  the reduction to a real Schur form of the state
-C                   matrix of a minimal realization of W failed;
-C             = 7:  a failure was detected during the ordering of the
-C                   real Schur form of the state matrix of a minimal
-C                   realization of W or in the iterative process to
-C                   compute a right coprime factorization with inner
-C                   denominator;
-C             = 8:  if DICO = 'C' and the matrix AW has a controllable
-C                   eigenvalue on the imaginary axis, or DICO = 'D' and
-C                   AW has a controllable eigenvalue on the unit circle;
-C             = 9:  the computation of eigenvalues failed;
-C             = 10: the computation of Hankel singular values failed.
-C
-C     METHOD
-C
-C     Let G be the transfer-function matrix of the original
-C     linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t) + Du(t),                          (1)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system. The subroutine AB09ID determines
-C     the matrices of a reduced order system
-C
-C          d[z(t)] = Ar*z(t) + Br*u(t)
-C          yr(t)   = Cr*z(t) + Dr*u(t),                      (2)
-C
-C     such that the corresponding transfer-function matrix Gr minimizes
-C     the norm of the frequency-weighted error
-C
-C             V*(G-Gr)*W,                                    (3)
-C
-C     where V and W are transfer-function matrices without poles on the
-C     imaginary axis in continuous-time case or on the unit circle in
-C     discrete-time case.
-C
-C     The following procedure is used to reduce G:
-C
-C     1) Decompose additively G, of order N, as
-C
-C          G = G1 + G2,
-C
-C        such that G1 = (A1,B1,C1,D) has only ALPHA-stable poles and
-C        G2 = (A2,B2,C2,0), of order NU, has only ALPHA-unstable poles.
-C
-C     2) Compute for G1 a B&T or SPA frequency-weighted approximation
-C        G1r of order NR-NU using the combination method or the
-C        modified combination method of [4].
-C
-C     3) Assemble the reduced model Gr as
-C
-C           Gr = G1r + G2.
-C
-C     For the frequency-weighted reduction of the ALPHA-stable part,
-C     several methods described in [4] can be employed in conjunction
-C     with the combination method and modified combination method
-C     proposed in [4].
-C
-C     If JOB = 'B', the square-root B&T method is used.
-C     If JOB = 'F', the balancing-free square-root version of the
-C     B&T method is used.
-C     If JOB = 'S', the square-root version of the SPA method is used.
-C     If JOB = 'P', the balancing-free square-root version of the
-C     SPA method is used.
-C
-C     For each of these methods, left and right truncation matrices
-C     are determined using the Cholesky factors of an input
-C     frequency-weighted controllability Grammian P and an output
-C     frequency-weighted observability Grammian Q.
-C     P and Q are computed from the controllability Grammian Pi of G*W
-C     and the observability Grammian Qo of V*G. Using special
-C     realizations of G*W and V*G, Pi and Qo are computed in the
-C     partitioned forms
-C
-C           Pi = ( P11  P12 )   and    Qo = ( Q11  Q12 ) ,
-C                ( P12' P22 )               ( Q12' Q22 )
-C
-C     where P11 and Q11 are the leading N-by-N parts of Pi and Qo,
-C     respectively. Let P0 and Q0 be non-negative definite matrices
-C     defined below
-C                                        -1
-C            P0 = P11 - ALPHAC**2*P12*P22 *P21 ,
-C                                        -1
-C            Q0 = Q11 - ALPHAO**2*Q12*Q22 *Q21.
-C
-C     The frequency-weighted controllability and observability
-C     Grammians, P and Q, respectively, are defined as follows:
-C     P = P0 if JOBC = 'S' (standard combination method [4]);
-C     P = P1 >= P0 if JOBC = 'E', where P1 is the controllability
-C     Grammian defined to enforce stability for a modified combination
-C     method of [4];
-C     Q = Q0 if JOBO = 'S' (standard combination method [4]);
-C     Q = Q1 >= Q0 if JOBO = 'E', where Q1 is the observability
-C     Grammian defined to enforce stability for a modified combination
-C     method of [4].
-C
-C     If JOBC = JOBO = 'S' and ALPHAC = ALPHAO = 0, the choice of
-C     Grammians corresponds to the method of Enns [1], while if
-C     ALPHAC = ALPHAO = 1, the choice of Grammians corresponds
-C     to the method of Lin and Chiu [2,3].
-C
-C     If JOBC = 'S' and ALPHAC = 1, no pole-zero cancellations must
-C     occur in G*W. If JOBO = 'S' and ALPHAO = 1, no pole-zero
-C     cancellations must occur in V*G. The presence of pole-zero
-C     cancellations leads to meaningless results and must be avoided.
-C
-C     The frequency-weighted Hankel singular values HSV(1), ....,
-C     HSV(N) are computed as the square roots of the eigenvalues
-C     of the product P*Q.
-C
-C     REFERENCES
-C
-C     [1] Enns, D.
-C         Model reduction with balanced realizations: An error bound
-C         and a frequency weighted generalization.
-C         Proc. 23-th CDC, Las Vegas, pp. 127-132, 1984.
-C
-C     [2] Lin, C.-A. and Chiu, T.-Y.
-C         Model reduction via frequency-weighted balanced realization.
-C         Control Theory and Advanced Technology, vol. 8,
-C         pp. 341-351, 1992.
-C
-C     [3] Sreeram, V., Anderson, B.D.O and Madievski, A.G.
-C         New results on frequency weighted balanced reduction
-C         technique.
-C         Proc. ACC, Seattle, Washington, pp. 4004-4009, 1995.
-C
-C     [4] Varga, A. and Anderson, B.D.O.
-C         Square-root balancing-free methods for the frequency-weighted
-C         balancing related model reduction.
-C         (report in preparation)
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on accuracy enhancing square-root
-C     techniques.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, August 2000.
-C     D. Sima, University of Bucharest, August 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 2000.
-C
-C     REVISIONS
-C
-C     A. Varga, Australian National University, Canberra, November 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Dec. 2000,
-C              Sep. 2001.
-C
-C     KEYWORDS
-C
-C     Frequency weighting, model reduction, multivariable system,
-C     state-space model, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  C100, ONE, ZERO
-      PARAMETER         ( C100 = 100.0D0, ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, EQUIL, JOB, JOBC, JOBO, ORDSEL, WEIGHT
-      INTEGER           INFO, IWARN, LDA, LDAV, LDAW, LDB, LDBV, LDBW,
-     $                  LDC, LDCV, LDCW, LDD, LDDV, LDDW, LDWORK, M, MW,
-     $                  N, NR, NS, NV, NW, P, PV
-      DOUBLE PRECISION  ALPHA, ALPHAC, ALPHAO, TOL1, TOL2
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), AV(LDAV,*), AW(LDAW,*),
-     $                  B(LDB,*), BV(LDBV,*), BW(LDBW,*),
-     $                  C(LDC,*), CV(LDCV,*), CW(LDCW,*),
-     $                  D(LDD,*), DV(LDDV,*), DW(LDDW,*), DWORK(*),
-     $                  HSV(*)
-C     .. Local Scalars ..
-      LOGICAL           BAL, BTA, DISCR, FIXORD, FRWGHT, LEFTW, RIGHTW,
-     $                  SCALE, SPA
-      INTEGER           IERR, IWARNL, KBR, KBV, KBW, KCR, KCV, KCW, KDR,
-     $                  KDV, KI, KL, KT, KTI, KU, KW, LCF, LDW, LW, NMR,
-     $                  NN, NNQ, NNR, NNV, NNW, NRA, NU, NU1, NVR, NWR,
-     $                  PPV, WRKOPT
-      DOUBLE PRECISION  ALPWRK, MAXRED, SCALEC, SCALEO
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH
-      EXTERNAL          DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB09IX, AB09IY, DLACPY, SB08CD, SB08DD, TB01ID,
-     $                  TB01KD, TB01PD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         ABS, INT, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      DISCR  = LSAME( DICO,   'D' )
-      BTA    = LSAME( JOB,    'B' ) .OR. LSAME( JOB, 'F' )
-      SPA    = LSAME( JOB,    'S' ) .OR. LSAME( JOB, 'P' )
-      BAL    = LSAME( JOB,    'B' ) .OR. LSAME( JOB, 'S' )
-      SCALE  = LSAME( EQUIL,  'S' )
-      FIXORD = LSAME( ORDSEL, 'F' )
-      LEFTW  = LSAME( WEIGHT, 'L' ) .OR. LSAME( WEIGHT, 'B' )
-      RIGHTW = LSAME( WEIGHT, 'R' ) .OR. LSAME( WEIGHT, 'B' )
-      FRWGHT = LEFTW .OR. RIGHTW
-C
-      LW  = 1
-      NN  = N*N
-      NNV = N + NV
-      NNW = N + NW
-      PPV = MAX( P, PV )
-C
-      IF( LEFTW .AND. PV.GT.0 ) THEN
-         LW = MAX( LW, NNV*( NNV + MAX( NNV, PV ) + 5 ) )
-      ELSE
-         LW = MAX( LW, N*( P + 5 ) )
-      END IF
-C
-      IF( RIGHTW .AND. MW.GT.0 ) THEN
-         LW = MAX( LW, NNW*( NNW + MAX( NNW, MW ) + 5 ) )
-      ELSE
-         LW = MAX( LW, N*( M + 5 ) )
-      END IF
-      LW = 2*NN + MAX( LW, 2*NN + 5*N, N*MAX( M, P ) )
-C
-      IF( LEFTW .AND. NV.GT.0 ) THEN
-         LCF = PV*( NV + PV ) + PV*NV +
-     $         MAX( NV*( NV + 5 ), PV*( PV + 2 ), 4*PPV )
-         IF( PV.EQ.P ) THEN
-            LW = MAX( LW, LCF, NV + MAX( NV, 3*P ) )
-         ELSE
-            LW = MAX( LW, PPV*( 2*NV + PPV ) +
-     $                    MAX( LCF, NV + MAX( NV, 3*PPV ) ) )
-         END IF
-      END IF
-C
-      IF( RIGHTW .AND. NW.GT.0 ) THEN
-         IF( MW.EQ.M ) THEN
-            LW = MAX( LW, NW + MAX( NW, 3*M ) )
-         ELSE
-            LW = MAX( LW, 2*NW*MAX( M, MW ) +
-     $                    NW + MAX( NW, 3*M, 3*MW ) )
-         END IF
-         LW = MAX( LW, MW*( NW + MW ) +
-     $             MAX( NW*( NW + 5 ), MW*( MW + 2 ), 4*MW, 4*M ) )
-      END IF
-C
-C     Check the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( LSAME( JOBC, 'S' ) .OR. LSAME( JOBC, 'E' ) ) )
-     $     THEN
-         INFO = -2
-      ELSE IF( .NOT.( LSAME( JOBO, 'S' ) .OR. LSAME( JOBO, 'E' ) ) )
-     $     THEN
-         INFO = -3
-      ELSE IF( .NOT. ( BTA .OR. SPA ) ) THEN
-         INFO = -4
-      ELSE IF( .NOT. ( FRWGHT .OR. LSAME( WEIGHT, 'N' ) ) ) THEN
-         INFO = -5
-      ELSE IF( .NOT. ( SCALE  .OR. LSAME( EQUIL,  'N' ) ) ) THEN
-         INFO = -6
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -7
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -8
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -9
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -10
-      ELSE IF( NV.LT.0 ) THEN
-         INFO = -11
-      ELSE IF( PV.LT.0 ) THEN
-         INFO = -12
-      ELSE IF( NW.LT.0 ) THEN
-         INFO = -13
-      ELSE IF( MW.LT.0 ) THEN
-         INFO = -14
-      ELSE IF( FIXORD .AND. ( NR.LT.0 .OR. NR.GT.N ) ) THEN
-         INFO = -15
-      ELSE IF( ( DISCR .AND. ( ALPHA.LT.ZERO .OR. ALPHA.GT.ONE ) ) .OR.
-     $    ( .NOT.DISCR .AND.   ALPHA.GT.ZERO ) ) THEN
-         INFO = -16
-      ELSE IF( ABS( ALPHAC ).GT.ONE  ) THEN
-         INFO = -17
-      ELSE IF( ABS( ALPHAO ).GT.ONE  ) THEN
-         INFO = -18
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -20
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -22
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -24
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -26
-      ELSE IF( LDAV.LT.1 .OR. ( LEFTW  .AND. LDAV.LT.NV ) ) THEN
-         INFO = -28
-      ELSE IF( LDBV.LT.1 .OR. ( LEFTW  .AND. LDBV.LT.NV ) ) THEN
-         INFO = -30
-      ELSE IF( LDCV.LT.1 .OR. ( LEFTW  .AND. LDCV.LT.PV ) ) THEN
-         INFO = -32
-      ELSE IF( LDDV.LT.1 .OR. ( LEFTW  .AND. LDDV.LT.PV ) ) THEN
-         INFO = -34
-      ELSE IF( LDAW.LT.1 .OR. ( RIGHTW .AND. LDAW.LT.NW ) ) THEN
-         INFO = -36
-      ELSE IF( LDBW.LT.1 .OR. ( RIGHTW .AND. LDBW.LT.NW ) ) THEN
-         INFO = -38
-      ELSE IF( LDCW.LT.1 .OR. ( RIGHTW .AND. LDCW.LT.M  ) ) THEN
-         INFO = -40
-      ELSE IF( LDDW.LT.1 .OR. ( RIGHTW .AND. LDDW.LT.M  ) ) THEN
-         INFO = -42
-      ELSE IF( TOL2.GT.ZERO .AND. .NOT.FIXORD .AND. TOL2.GT.TOL1 ) THEN
-         INFO = -46
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -49
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09ID', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 ) THEN
-         NR = 0
-         NS = 0
-         IWORK(1) = 0
-         IWORK(2) = NV
-         IWORK(3) = NW
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      IF( SCALE ) THEN
-C
-C        Scale simultaneously the matrices A, B and C:
-C        A <- inv(D)*A*D, B <- inv(D)*B and C <- C*D, where D is a
-C        diagonal matrix.
-C        Workspace: N.
-C
-         MAXRED = C100
-         CALL TB01ID( 'All', N, M, P, MAXRED, A, LDA, B, LDB, C, LDC,
-     $                DWORK, INFO )
-      END IF
-C
-C     Correct the value of ALPHA to ensure stability.
-C
-      ALPWRK = ALPHA
-      IF( DISCR ) THEN
-         IF( ALPHA.EQ.ONE ) ALPWRK = ONE - SQRT( DLAMCH( 'E' ) )
-      ELSE
-         IF( ALPHA.EQ.ZERO ) ALPWRK = -SQRT( DLAMCH( 'E' ) )
-      END IF
-C
-C     Allocate working storage.
-C
-      KU = 1
-      KL = KU + NN
-      KI = KL + N
-      KW = KI + N
-C
-C     Reduce A to a block-diagonal real Schur form, with the
-C     ALPHA-unstable part in the leading diagonal position, using a
-C     non-orthogonal similarity transformation, A <- inv(T)*A*T, and
-C     apply the transformation to B and C: B <- inv(T)*B and C <- C*T.
-C
-C     Workspace needed:      N*(N+2);
-C     Additional workspace:  need   3*N;
-C                            prefer larger.
-C
-      CALL TB01KD( DICO, 'Unstable', 'General', N, M, P, ALPWRK, A, LDA,
-     $             B, LDB, C, LDC, NU, DWORK(KU), N, DWORK(KL),
-     $             DWORK(KI), DWORK(KW), LDWORK-KW+1, IERR )
-C
-      IF( IERR.NE.0 ) THEN
-         IF( IERR.NE.3 ) THEN
-            INFO = 1
-         ELSE
-            INFO = 2
-         END IF
-         RETURN
-      END IF
-C
-      WRKOPT = INT( DWORK(KW) ) + KW - 1
-C
-C     Determine NRA, the desired order for the reduction of stable part.
-C
-      IWARNL = 0
-      NS = N - NU
-      IF( FIXORD ) THEN
-         NRA = MAX( 0, NR-NU )
-         IF( NR.LT.NU )
-     $      IWARNL = 3
-      ELSE
-         NRA = 0
-      END IF
-C
-C     Finish if only unstable part is present.
-C
-      IF( NS.EQ.0 ) THEN
-         NR = NU
-         DWORK(1) = WRKOPT
-         IWORK(1) = 0
-         IWORK(2) = NV
-         IWORK(3) = NW
-         RETURN
-      END IF
-C
-      NVR = NV
-      IF( LEFTW .AND. NV.GT.0 ) THEN
-C
-C        Compute a left-coprime factorization with inner denominator
-C        of a minimal realization of V. The resulting AV is in
-C        real Schur form.
-C        Workspace needed:   real  LV+MAX( 1, LCF,
-C                                          NV + MAX( NV, 3*P, 3*PV ) ),
-C                                  where
-C                                  LV = 0 if P = PV and
-C                                  LV = MAX(P,PV)*(2*NV+MAX(P,PV))
-C                                         otherwise;
-C                                  LCF = PV*(NV+PV) +
-C                                        MAX( 1, PV*NV + MAX( NV*(NV+5),
-C                                             PV*(PV+2),4*PV,4*P ) );
-C                                  prefer larger;
-C                          integer NV + MAX(P,PV).
-C
-         IF( P.EQ.PV ) THEN
-            KW = 1
-            CALL TB01PD( 'Minimal', 'Scale', NV, P, PV, AV, LDAV,
-     $                   BV, LDBV, CV, LDCV, NVR, ZERO,
-     $                   IWORK, DWORK, LDWORK, INFO )
-            WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-            KBR = 1
-            KDR = KBR + PV*NVR
-            KW  = KDR + PV*PV
-            CALL SB08CD( DICO, NVR, P, PV, AV, LDAV, BV, LDBV, CV, LDCV,
-     $                   DV, LDDV, NNQ, NNR, DWORK(KBR), MAX( 1, NVR ),
-     $                   DWORK(KDR), PV, ZERO, DWORK(KW), LDWORK-KW+1,
-     $                   IWARN, IERR )
-         ELSE
-            LDW = MAX( P, PV )
-            KBV = 1
-            KCV = KBV + NV*LDW
-            KW  = KCV + NV*LDW
-            CALL DLACPY( 'Full', NV, P, BV, LDBV, DWORK(KBV), NV )
-            CALL DLACPY( 'Full', PV, NV, CV, LDCV, DWORK(KCV), LDW )
-            CALL TB01PD( 'Minimal', 'Scale', NV, P, PV, AV, LDAV,
-     $                   DWORK(KBV), NV, DWORK(KCV), LDW, NVR, ZERO,
-     $                   IWORK, DWORK(KW), LDWORK-KW+1, INFO )
-            KDV = KW
-            KBR = KDV + LDW*LDW
-            KDR = KBR + PV*NVR
-            KW  = KDR + PV*PV
-            CALL DLACPY( 'Full', PV, P, DV, LDDV, DWORK(KDV), LDW )
-            CALL SB08CD( DICO, NVR, P, PV, AV, LDAV, DWORK(KBV), NV,
-     $                   DWORK(KCV), LDW, DWORK(KDV), LDW, NNQ, NNR,
-     $                   DWORK(KBR), MAX( 1, NVR ), DWORK(KDR), PV,
-     $                   ZERO, DWORK(KW), LDWORK-KW+1, IWARN, IERR )
-            CALL DLACPY( 'Full', NVR, P, DWORK(KBV), NV, BV, LDBV )
-            CALL DLACPY( 'Full', PV, NVR, DWORK(KCV), LDW, CV, LDCV )
-            CALL DLACPY( 'Full', PV, P, DWORK(KDV), LDW, DV, LDDV )
-         END IF
-         IF( IERR.NE.0 ) THEN
-            INFO = IERR + 2
-            RETURN
-         END IF
-         NVR = NNQ
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         IF( IWARN.GT.0 )
-     $      IWARN = 10 + IWARN
-      END IF
-C
-      NWR = NW
-      IF( RIGHTW .AND. NW.GT.0 ) THEN
-C
-C        Compute a minimal realization of W.
-C        Workspace needed:   real  LW+MAX(1, NW + MAX(NW, 3*M, 3*MW));
-C                                  where
-C                                  LW = 0,              if M = MW and
-C                                  LW = 2*NW*MAX(M,MW), otherwise;
-C                                  prefer larger;
-C                          integer NW + MAX(M,MW).
-C
-         IF( M.EQ.MW ) THEN
-            KW = 1
-            CALL TB01PD( 'Minimal', 'Scale', NW, MW, M, AW, LDAW,
-     $                   BW, LDBW, CW, LDCW, NWR, ZERO, IWORK, DWORK,
-     $                   LDWORK, INFO )
-         ELSE
-            LDW = MAX( M, MW )
-            KBW = 1
-            KCW = KBW + NW*LDW
-            KW  = KCW + NW*LDW
-            CALL DLACPY( 'Full', NW, MW, BW, LDBW, DWORK(KBW), NW )
-            CALL DLACPY( 'Full', M, NW, CW, LDCW, DWORK(KCW), LDW )
-            CALL TB01PD( 'Minimal', 'Scale', NW, MW, M, AW, LDAW,
-     $                   DWORK(KBW), NW, DWORK(KCW), LDW, NWR, ZERO,
-     $                   IWORK, DWORK(KW), LDWORK-KW+1, INFO )
-            CALL DLACPY( 'Full', NWR, MW, DWORK(KBW), NW, BW, LDBW )
-            CALL DLACPY( 'Full', M, NWR, DWORK(KCW), LDW, CW, LDCW )
-         END IF
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      END IF
-C
-      IF( RIGHTW .AND. NWR.GT.0 ) THEN
-C
-C        Compute a right-coprime factorization with inner denominator
-C        of the minimal realization of W. The resulting AW is in
-C        real Schur form.
-C
-C        Workspace needed:  MW*(NW+MW) +
-C                           MAX( 1, NW*(NW+5), MW*(MW+2), 4*MW, 4*M );
-C                           prefer larger.
-C
-         LDW = MAX( 1, MW )
-         KCR = 1
-         KDR = KCR + NWR*LDW
-         KW  = KDR + MW*LDW
-         CALL SB08DD( DICO, NWR, MW, M, AW, LDAW, BW, LDBW, CW, LDCW,
-     $                DW, LDDW, NNQ, NNR, DWORK(KCR), LDW, DWORK(KDR),
-     $                LDW, ZERO, DWORK(KW), LDWORK-KW+1, IWARN, IERR )
-         IF( IERR.NE.0 ) THEN
-            INFO = IERR + 5
-            RETURN
-         END IF
-         NWR = NNQ
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         IF( IWARN.GT.0 )
-     $      IWARN = 10 + IWARN
-      END IF
-C
-      NU1 = NU + 1
-C
-C     Allocate working storage.
-C
-      KT  = 1
-      KTI = KT  + NN
-      KW  = KTI + NN
-C
-C     Compute in DWORK(KTI) and DWORK(KT) the Cholesky factors S and R
-C     of the controllability and observability Grammians, respectively.
-C     Real workspace:    need  2*N*N + MAX( 1, LLEFT, LRIGHT ),
-C             where
-C             LLEFT  = (N+NV)*(N+NV+MAX(N+NV,PV)+5)
-C                              if WEIGHT = 'L' or 'B' and PV > 0;
-C             LLEFT  = N*(P+5) if WEIGHT = 'R' or 'N' or  PV = 0;
-C             LRIGHT = (N+NW)*(N+NW+MAX(N+NW,MW)+5)
-C                              if WEIGHT = 'R' or 'B' and MW > 0;
-C             LRIGHT = N*(M+5) if WEIGHT = 'L' or 'N' or  MW = 0.
-C                        prefer larger.
-C
-      CALL AB09IY( DICO, JOBC, JOBO, WEIGHT, NS, M, P, NVR, PV, NWR,
-     $             MW, ALPHAC, ALPHAO, A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $             C(1,NU1), LDC, AV, LDAV, BV, LDBV, CV, LDCV,
-     $             DV, LDDV, AW, LDAW, BW, LDBW, CW, LDCW, DW, LDDW,
-     $             SCALEC, SCALEO, DWORK(KTI), N, DWORK(KT), N,
-     $             DWORK(KW), LDWORK-KW+1, IERR )
-      IF( IERR.NE.0 ) THEN
-         INFO = 9
-         RETURN
-      END IF
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Compute a BTA or SPA of the stable part.
-C     Real workspace:  need  2*N*N + MAX( 1, 2*N*N+5*N, N*MAX(M,P) ).
-C
-      CALL AB09IX( DICO, JOB, 'Schur', ORDSEL, NS, M, P, NRA,
-     $             SCALEC, SCALEO, A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $             C(1,NU1), LDC, D, LDD, DWORK(KTI), N, DWORK(KT), N,
-     $             NMR, HSV, TOL1, TOL2, IWORK, DWORK(KW), LDWORK-KW+1,
-     $             IWARN, IERR )
-      IWARN = MAX( IWARN, IWARNL )
-      IF( IERR.NE.0 ) THEN
-         INFO = 10
-         RETURN
-      END IF
-      NR = NRA + NU
-C
-      DWORK(1) = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      IWORK(1) = NMR
-      IWORK(2) = NVR
-      IWORK(3) = NWR
-C
-      RETURN
-C *** Last line of AB09ID ***
-      END
--- a/extra/control-devel/src/AB09IX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,695 +0,0 @@
-      SUBROUTINE AB09IX( DICO, JOB, FACT, ORDSEL, N, M, P, NR,
-     $                   SCALEC, SCALEO, A, LDA, B, LDB, C, LDC, D, LDD,
-     $                   TI, LDTI, T, LDT, NMINR, HSV, TOL1, TOL2,
-     $                   IWORK, DWORK, LDWORK, IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order model (Ar,Br,Cr,Dr) for an original
-C     state-space representation (A,B,C,D) by using the square-root or
-C     balancing-free square-root Balance & Truncate (B&T) or
-C     Singular Perturbation Approximation (SPA) model reduction methods.
-C     The computation of truncation matrices TI and T is based on
-C     the Cholesky factor S of a controllability Grammian P = S*S'
-C     and the Cholesky factor R of an observability Grammian Q = R'*R,
-C     where S and R are given upper triangular matrices.
-C
-C     For the B&T approach, the matrices of the reduced order system
-C     are computed using the truncation formulas:
-C
-C          Ar = TI * A * T ,  Br = TI * B ,  Cr = C * T .     (1)
-C
-C     For the SPA approach, the matrices of a minimal realization
-C     (Am,Bm,Cm) are computed using the truncation formulas:
-C
-C          Am = TI * A * T ,  Bm = TI * B ,  Cm = C * T .     (2)
-C
-C     Am, Bm, Cm and D serve further for computing the SPA of the given
-C     system.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     JOB     CHARACTER*1
-C             Specifies the model reduction approach to be used
-C             as follows:
-C             = 'B':  use the square-root B&T method;
-C             = 'F':  use the balancing-free square-root B&T method;
-C             = 'S':  use the square-root SPA method;
-C             = 'P':  use the balancing-free square-root SPA method.
-C
-C     FACT    CHARACTER*1
-C             Specifies whether or not, on entry, the matrix A is in a
-C             real Schur form, as follows:
-C             = 'S':  A is in a real Schur form;
-C             = 'N':  A is a general dense square matrix.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting order NR is fixed;
-C             = 'A':  the resulting order NR is automatically determined
-C                     on basis of the given tolerance TOL1.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation,
-C             i.e., the order of the matrix A.  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     NR      (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NR is the desired order of
-C             the resulting reduced order system.  0 <= NR <= N.
-C             On exit, if INFO = 0, NR is the order of the resulting
-C             reduced order model. NR is set as follows:
-C             if ORDSEL = 'F', NR is equal to MIN(NR,NMINR), where NR
-C             is the desired order on entry and NMINR is the number of
-C             the Hankel singular values greater than N*EPS*S1, where
-C             EPS is the machine precision (see LAPACK Library Routine
-C             DLAMCH) and S1 is the largest Hankel singular value
-C             (computed in HSV(1));
-C             NR can be further reduced to ensure HSV(NR) > HSV(NR+1);
-C             if ORDSEL = 'A', NR is equal to the number of Hankel
-C             singular values greater than MAX(TOL1,N*EPS*S1).
-C
-C     SCALEC  (input) DOUBLE PRECISION
-C             Scaling factor for the Cholesky factor S of the
-C             controllability Grammian, i.e., S/SCALEC is used to
-C             compute the Hankel singular values.  SCALEC > 0.
-C
-C     SCALEO  (input) DOUBLE PRECISION
-C             Scaling factor for the Cholesky factor R of the
-C             observability Grammian, i.e., R/SCALEO is used to
-C             compute the Hankel singular values.  SCALEO > 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A. If FACT = 'S',
-C             A is in a real Schur form.
-C             On exit, if INFO = 0, the leading NR-by-NR part of this
-C             array contains the state dynamics matrix Ar of the
-C             reduced order system.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, if INFO = 0, the leading NR-by-M part of this
-C             array contains the input/state matrix Br of the reduced
-C             order system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, if INFO = 0, the leading P-by-NR part of this
-C             array contains the state/output matrix Cr of the reduced
-C             order system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, if JOB = 'S' or JOB = 'P', the leading P-by-M
-C             part of this array must contain the original input/output
-C             matrix D.
-C             On exit, if INFO = 0 and JOB = 'S' or JOB = 'P', the
-C             leading P-by-M part of this array contains the
-C             input/output matrix Dr of the reduced order system.
-C             If JOB = 'B' or JOB = 'F', this array is not referenced.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.
-C             LDD >= 1,        if JOB = 'B' or JOB = 'F';
-C             LDD >= MAX(1,P), if JOB = 'S' or JOB = 'P'.
-C
-C     TI      (input/output) DOUBLE PRECISION array, dimension (LDTI,N)
-C             On entry, the leading N-by-N upper triangular part of
-C             this array must contain the Cholesky factor S of a
-C             controllability Grammian P = S*S'.
-C             On exit, if INFO = 0, and NR > 0, the leading NMINR-by-N
-C             part of this array contains the left truncation matrix
-C             TI in (1), for the B&T approach, or in (2), for the
-C             SPA approach.
-C
-C     LDTI    INTEGER
-C             The leading dimension of array TI.  LDTI >= MAX(1,N).
-C
-C     T       (input/output) DOUBLE PRECISION array, dimension (LDT,N)
-C             On entry, the leading N-by-N upper triangular part of
-C             this array must contain the Cholesky factor R of an
-C             observability Grammian Q = R'*R.
-C             On exit, if INFO = 0, and NR > 0, the leading N-by-NMINR
-C             part of this array contains the right truncation matrix
-C             T in (1), for the B&T approach, or in (2), for the
-C             SPA approach.
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.  LDT >= MAX(1,N).
-C
-C     NMINR   (output) INTEGER
-C             The number of Hankel singular values greater than
-C             MAX(TOL2,N*EPS*S1).
-C             Note: If S and R are the Cholesky factors of the
-C             controllability and observability Grammians of the
-C             original system (A,B,C,D), respectively, then NMINR is
-C             the order of a minimal realization of the original system.
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, it contains the Hankel singular values,
-C             ordered decreasingly. The Hankel singular values are
-C             singular values of the product R*S.
-C
-C     Tolerances
-C
-C     TOL1    DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL1 contains the tolerance for
-C             determining the order of the reduced system.
-C             For model reduction, the recommended value lies in the
-C             interval [0.00001,0.001].
-C             If TOL1 <= 0 on entry, the used default value is
-C             TOL1 = N*EPS*S1, where EPS is the machine precision
-C             (see LAPACK Library Routine DLAMCH) and S1 is the largest
-C             Hankel singular value (computed in HSV(1)).
-C             If ORDSEL = 'F', the value of TOL1 is ignored.
-C
-C     TOL2    DOUBLE PRECISION
-C             The tolerance for determining the order of a minimal
-C             realization of the system.
-C             The recommended value is TOL2 = N*EPS*S1.
-C             This value is used by default if TOL2 <= 0 on entry.
-C             If TOL2 > 0, and ORDSEL = 'A', then TOL2 <= TOL1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension LIWORK, where
-C             LIWORK = 0,   if JOB = 'B';
-C             LIWORK = N,   if JOB = 'F';
-C             LIWORK = 2*N, if JOB = 'S' or 'P'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX( 1, 2*N*N + 5*N, N*MAX(M,P) ).
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NR is greater
-C                   than NMINR, the order of a minimal realization of
-C                   the given system; in this case, the resulting NR is
-C                   set automatically to NMINR;
-C             = 2:  with ORDSEL = 'F', the selected order NR corresponds
-C                   to repeated singular values, which are neither all
-C                   included nor all excluded from the reduced model;
-C                   in this case, the resulting NR is set automatically
-C                   to the largest value such that HSV(NR) > HSV(NR+1).
-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 computation of Hankel singular values failed.
-C
-C     METHOD
-C
-C     Let be the stable linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t) + Du(t),                             (3)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system. The subroutine AB09IX determines for
-C     the given system (3), the matrices of a reduced NR order system
-C
-C          d[z(t)] = Ar*z(t) + Br*u(t)
-C          yr(t)   = Cr*z(t) + Dr*u(t),                         (4)
-C
-C     by using the square-root or balancing-free square-root
-C     Balance & Truncate (B&T) or Singular Perturbation Approximation
-C     (SPA) model reduction methods.
-C
-C     The projection matrices TI and T are determined using the
-C     Cholesky factors S and R of a controllability Grammian P and an
-C     observability Grammian Q.
-C     The Hankel singular values HSV(1), ...., HSV(N) are computed as
-C     singular values of the product R*S.
-C
-C     If JOB = 'B', the square-root Balance & Truncate technique
-C     of [1] is used.
-C
-C     If JOB = 'F', the balancing-free square-root version of the
-C     Balance & Truncate technique [2] is used.
-C
-C     If JOB = 'S', the square-root version of the Singular Perturbation
-C     Approximation method [3,4] is used.
-C
-C     If JOB = 'P', the balancing-free square-root version of the
-C     Singular Perturbation Approximation method [3,4] is used.
-C
-C     REFERENCES
-C
-C     [1] Tombs M.S. and Postlethwaite I.
-C         Truncated balanced realization of stable, non-minimal
-C         state-space systems.
-C         Int. J. Control, Vol. 46, pp. 1319-1330, 1987.
-C
-C     [2] Varga A.
-C         Efficient minimal realization procedure based on balancing.
-C         Proc. of IMACS/IFAC Symp. MCTS, Lille, France, May 1991,
-C         A. El Moudni, P. Borne, S. G. Tzafestas (Eds.),
-C         Vol. 2, pp. 42-46.
-C
-C     [3] Liu Y. and Anderson B.D.O.
-C         Singular Perturbation Approximation of balanced systems.
-C         Int. J. Control, Vol. 50, pp. 1379-1405, 1989.
-C
-C     [4] Varga A.
-C         Balancing-free square-root algorithm for computing singular
-C         perturbation approximations.
-C         Proc. 30-th CDC, Brighton, Dec. 11-13, 1991,
-C         Vol. 2, pp. 1062-1065.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method relies on accuracy enhancing square-root
-C     or balancing-free square-root methods.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, August 2000.
-C     D. Sima, University of Bucharest, August 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 2000.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Dec. 2000,
-C              Sep. 2001.
-C
-C     KEYWORDS
-C
-C     Balance and truncate, minimal state-space representation,
-C     model reduction, multivariable system,
-C     singular perturbation approximation, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, FACT, JOB, ORDSEL
-      INTEGER           INFO, IWARN, LDA, LDB, LDC, LDD, LDT, LDTI,
-     $                  LDWORK, M, N, NMINR, NR, P
-      DOUBLE PRECISION  SCALEC, SCALEO, TOL1, TOL2
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                  DWORK(*), HSV(*), T(LDT,*), TI(LDTI,*)
-C     .. Local Scalars ..
-      LOGICAL           BAL, BTA, DISCR, FIXORD, RSF, SPA
-      INTEGER           IERR, IJ, J, K, KTAU, KU, KV, KW, LDW, LW,
-     $                  NRED, NR1, NS, WRKOPT
-      DOUBLE PRECISION  ATOL, RCOND, SKP, TEMP, TOLDEF
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH
-      EXTERNAL          DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB09DD, DGEMM,  DGEMV, DGEQRF, DGETRF, DGETRS,
-     $                  DLACPY, DORGQR, DSCAL, DTRMM,  DTRMV,  MA02AD,
-     $                  MB03UD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, INT, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      DISCR  = LSAME( DICO,   'D' )
-      BTA    = LSAME( JOB,    'B' ) .OR. LSAME( JOB, 'F' )
-      SPA    = LSAME( JOB,    'S' ) .OR. LSAME( JOB, 'P' )
-      BAL    = LSAME( JOB,    'B' ) .OR. LSAME( JOB, 'S' )
-      RSF    = LSAME( FACT,   'S' )
-      FIXORD = LSAME( ORDSEL, 'F' )
-C
-      LW = MAX( 1, 2*N*N + 5*N, N*MAX( M, P ) )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( BTA .OR. SPA ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( RSF .OR. LSAME( FACT, 'N' ) ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( FIXORD .AND. ( NR.LT.0 .OR. NR.GT.N ) ) THEN
-         INFO = -8
-      ELSE IF( SCALEC.LE.ZERO ) THEN
-         INFO = -9
-      ELSE IF( SCALEO.LE.ZERO ) THEN
-         INFO = -10
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -12
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -14
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -16
-      ELSE IF( LDD.LT.1 .OR. ( SPA .AND. LDD.LT.P ) ) THEN
-         INFO = -18
-      ELSE IF( LDTI.LT.MAX( 1, N ) ) THEN
-         INFO = -20
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -22
-      ELSE IF( TOL2.GT.ZERO .AND. .NOT.FIXORD .AND. TOL2.GT.TOL1 ) THEN
-         INFO = -26
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -29
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09IX', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 ) THEN
-         NR = 0
-         NMINR = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Save S in DWORK(KV).
-C
-      KV = 1
-      KU = KV + N*N
-      KW = KU + N*N
-      CALL DLACPY( 'Upper', N, N, TI, LDTI, DWORK(KV), N )
-C                             | x x |
-C     Compute R*S in the form | 0 x | in TI.
-C
-      DO 10 J = 1, N
-         CALL DTRMV( 'Upper', 'NoTranspose', 'NonUnit', J, T, LDT,
-     $               TI(1,J), 1 )
-   10 CONTINUE
-C
-C     Compute the singular value decomposition R*S = V*Sigma*UT of the
-C     upper triangular matrix R*S, with UT in TI and V in DWORK(KU).
-C
-C     Workspace:  need   2*N*N + 5*N;
-C                 prefer larger.
-C
-      CALL MB03UD( 'Vectors', 'Vectors', N, TI, LDTI, DWORK(KU), N, HSV,
-     $             DWORK(KW), LDWORK-KW+1, IERR )
-      IF( IERR.NE.0 ) THEN
-         INFO = 1
-         RETURN
-      ENDIF
-      WRKOPT = INT( DWORK(KW) ) + KW - 1
-C
-C     Scale the singular values.
-C
-      CALL DSCAL( N, ONE / SCALEC / SCALEO, HSV, 1 )
-C
-C     Partition Sigma, U and V conformally as:
-C
-C     Sigma = diag(Sigma1,Sigma2,Sigma3),  U = [U1,U2,U3] (U' in TI) and
-C     V = [V1,V2,V3] (in DWORK(KU)).
-C
-C     Compute NMINR, the order of a minimal realization, as the order
-C     of [Sigma1 Sigma2].
-C
-      TOLDEF = DBLE( N )*DLAMCH( 'Epsilon' )
-      ATOL   = MAX( TOL2, TOLDEF*HSV(1) )
-      NMINR  = N
-   20 IF( NMINR.GT.0 ) THEN
-         IF( HSV(NMINR).LE.ATOL ) THEN
-            NMINR = NMINR - 1
-            GO TO 20
-         END IF
-      END IF
-C
-C     Compute the order NR of reduced system, as the order of Sigma1.
-C
-      IF( FIXORD ) THEN
-C
-C        Check if the desired order is less than the order of a minimal
-C        realization.
-C
-         IF( NR.GT.NMINR ) THEN
-C
-C           Reduce the order to NMINR.
-C
-            NR = NMINR
-            IWARN = 1
-         END IF
-C
-C        Check for singular value multiplicity at cut-off point.
-C
-         IF( NR.GT.0 .AND. NR.LT.NMINR ) THEN
-            SKP = HSV(NR)
-            IF( SKP-HSV(NR+1).LE.TOLDEF*SKP ) THEN
-               IWARN = 2
-C
-C              Reduce the order such that HSV(NR) > HSV(NR+1).
-C
-   30          NR = NR - 1
-               IF( NR.GT.0 ) THEN
-                  IF( HSV(NR)-SKP.LE.TOLDEF*SKP ) GO TO 30
-               END IF
-            END IF
-         END IF
-      ELSE
-C
-C        The order is given as the number of singular values
-C        exceeding MAX( TOL1, N*EPS*HSV(1) ).
-C
-         ATOL = MAX( TOL1, ATOL )
-         NR   = 0
-         DO 40 J = 1, NMINR
-            IF( HSV(J).LE.ATOL ) GO TO 50
-            NR = NR + 1
-   40    CONTINUE
-   50    CONTINUE
-      ENDIF
-C
-C     Finish if the order is zero.
-C
-      IF( NR.EQ.0 ) THEN
-         IF( SPA )
-     $      CALL AB09DD( DICO, N, M, P, NR, A, LDA, B, LDB, C, LDC,
-     $                   D, LDD, RCOND, IWORK, DWORK, IERR )
-         DWORK(1) = WRKOPT
-         RETURN
-      END IF
-C
-C     Compute NS, the order of Sigma2. For BTA, NS = 0.
-C
-      IF( SPA ) THEN
-         NRED = NMINR
-      ELSE
-         NRED = NR
-      END IF
-      NS = NRED - NR
-C
-C     Compute the truncation matrices.
-C
-C     Compute TI' = | TI1' TI2' | = R'*| V1 V2 | in DWORK(KU).
-C
-      CALL DTRMM( 'Left', 'Upper', 'Transpose', 'NonUnit', N, NRED,
-     $            ONE, T, LDT, DWORK(KU), N )
-C
-C     Compute  T = | T1 T2 | = S*| U1 U2 | .
-C
-      CALL MA02AD( 'Full', NRED, N, TI, LDTI, T, LDT )
-      CALL DTRMM( 'Left', 'Upper', 'NoTranspose', 'NonUnit', N,
-     $            NRED, ONE, DWORK(KV), N, T, LDT )
-C
-      KTAU = KW
-      IF( BAL ) THEN
-         IJ = KU
-C
-C        Square-Root B&T/SPA method.
-C
-C        Compute the truncation matrices for balancing
-C                        -1/2                -1/2
-C               T1*Sigma1     and TI1'*Sigma1    .
-C
-         DO 60 J = 1, NR
-            TEMP = ONE/SQRT( HSV(J) )
-            CALL DSCAL( N, TEMP, T(1,J), 1 )
-            CALL DSCAL( N, TEMP, DWORK(IJ), 1 )
-            IJ = IJ + N
-   60    CONTINUE
-C
-      ELSE
-C
-C        Balancing-Free B&T/SPA method.
-C
-C        Compute orthogonal bases for the images of matrices T1 and
-C        TI1'.
-C
-C        Workspace:  need   2*N*N + 2*N;
-C                    prefer larger.
-C
-         KW   = KTAU + NR
-         LDW  = LDWORK - KW + 1
-         CALL DGEQRF( N, NR, T, LDT, DWORK(KTAU), DWORK(KW), LDW, IERR )
-         CALL DORGQR( N, NR, NR, T, LDT, DWORK(KTAU), DWORK(KW), LDW,
-     $                IERR )
-         CALL DGEQRF( N, NR, DWORK(KU), N, DWORK(KTAU), DWORK(KW), LDW,
-     $                IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         CALL DORGQR( N, NR, NR, DWORK(KU), N, DWORK(KTAU), DWORK(KW),
-     $                LDW, IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      ENDIF
-C
-      IF( NS.GT.0 ) THEN
-C
-C        Compute orthogonal bases for the images of matrices T2 and
-C        TI2'.
-C
-C        Workspace:  need   2*N*N + 2*N;
-C                    prefer larger.
-C
-         NR1 = NR + 1
-         KW  = KTAU + NS
-         LDW = LDWORK - KW + 1
-         CALL DGEQRF( N, NS, T(1,NR1), LDT, DWORK(KTAU), DWORK(KW), LDW,
-     $                IERR )
-         CALL DORGQR( N, NS, NS, T(1,NR1), LDT, DWORK(KTAU), DWORK(KW),
-     $                LDW, IERR )
-         CALL DGEQRF( N, NS, DWORK(KU+N*NR), N, DWORK(KTAU), DWORK(KW),
-     $                LDW, IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         CALL DORGQR( N, NS, NS, DWORK(KU+N*NR), N, DWORK(KTAU),
-     $                DWORK(KW), LDW, IERR )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      ENDIF
-C
-C     Transpose TI' in TI.
-C
-      CALL MA02AD( 'Full', N, NRED, DWORK(KU), N, TI, LDTI )
-C
-      IF( .NOT.BAL ) THEN
-C                        -1
-C        Compute (TI1*T1)  *TI1 in TI.
-C
-         CALL DGEMM( 'NoTranspose', 'NoTranspose', NR, NR, N, ONE, TI,
-     $               LDTI, T, LDT, ZERO, DWORK(KU), N )
-         CALL DGETRF( NR, NR, DWORK(KU), N, IWORK, IERR )
-         CALL DGETRS( 'NoTranspose', NR, N, DWORK(KU), N, IWORK, TI,
-     $                LDTI, IERR )
-C
-         IF( NS.GT.0 ) THEN
-C                           -1
-C           Compute (TI2*T2)  *TI2 in TI2.
-C
-            CALL DGEMM( 'NoTranspose', 'NoTranspose', NS, NS, N, ONE,
-     $                  TI(NR1,1), LDTI, T(1,NR1), LDT, ZERO, DWORK(KU),
-     $                  N )
-            CALL DGETRF( NS, NS, DWORK(KU), N, IWORK, IERR )
-            CALL DGETRS( 'NoTranspose', NS, N, DWORK(KU), N, IWORK,
-     $                   TI(NR1,1), LDTI, IERR )
-         END IF
-      END IF
-C
-C     Compute TI*A*T. Exploit RSF of A if possible.
-C     Workspace:  need   N*N.
-C
-      IF( RSF ) THEN
-         IJ = 1
-         DO 80 J = 1, N
-            K = MIN( J+1, N )
-            CALL DGEMV( 'NoTranspose', NRED, K, ONE, TI, LDTI,
-     $                  A(1,J), 1, ZERO, DWORK(IJ), 1 )
-            IJ = IJ + N
-   80    CONTINUE
-      ELSE
-         CALL DGEMM( 'NoTranspose', 'NoTranspose', NRED, N, N, ONE,
-     $               TI, LDTI, A, LDA, ZERO, DWORK, N )
-      END IF
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NRED, NRED, N, ONE,
-     $            DWORK, N, T, LDT, ZERO, A, LDA )
-C
-C     Compute TI*B and C*T.
-C     Workspace:  need   N*MAX(M,P).
-C
-      CALL DLACPY( 'Full', N, M, B, LDB, DWORK, N )
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NRED, M, N, ONE, TI,
-     $            LDTI, DWORK, N, ZERO, B, LDB )
-C
-      CALL DLACPY( 'Full', P, N, C, LDC, DWORK, P )
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', P, NRED, N, ONE,
-     $            DWORK, P, T, LDT, ZERO, C, LDC )
-C
-C     Compute the singular perturbation approximation if possible.
-C     Note that IERR = 1 on exit from AB09DD cannot appear here.
-C
-C     Workspace:  need real    4*(NMINR-NR);
-C                 need integer 2*(NMINR-NR).
-C
-      IF( SPA) THEN
-         CALL AB09DD( DICO, NRED, M, P, NR, A, LDA, B, LDB,
-     $                C, LDC, D, LDD, RCOND, IWORK, DWORK, IERR )
-      ELSE
-         NMINR = NR
-      END IF
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of AB09IX ***
-      END
--- a/extra/control-devel/src/AB09IY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,859 +0,0 @@
-      SUBROUTINE AB09IY( DICO, JOBC, JOBO, WEIGHT, N, M, P, NV, PV,
-     $                   NW, MW, ALPHAC, ALPHAO, A, LDA, B, LDB, C, LDC,
-     $                   AV, LDAV, BV, LDBV, CV, LDCV, DV, LDDV,
-     $                   AW, LDAW, BW, LDBW, CW, LDCW, DW, LDDW,
-     $                   SCALEC, SCALEO, S, LDS, R, LDR,
-     $                   DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute for given state-space representations
-C     (A,B,C,0), (AV,BV,CV,DV), and (AW,BW,CW,DW) of the
-C     transfer-function matrices G, V and W, respectively,
-C     the Cholesky factors of the frequency-weighted
-C     controllability and observability Grammians corresponding
-C     to a frequency-weighted model reduction problem.
-C     G, V and W must be stable transfer-function matrices with
-C     the state matrices A, AV, and AW in real Schur form.
-C     It is assumed that the state space realizations (AV,BV,CV,DV)
-C     and (AW,BW,CW,DW) are minimal. In case of possible pole-zero
-C     cancellations in forming V*G and/or G*W, the parameters for the
-C     choice of frequency-weighted Grammians ALPHAO and/or ALPHAC,
-C     respectively, must be different from 1.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the systems as follows:
-C             = 'C':  G, V and W are continuous-time systems;
-C             = 'D':  G, V and W are discrete-time systems.
-C
-C     JOBC    CHARACTER*1
-C             Specifies the choice of frequency-weighted controllability
-C             Grammian as follows:
-C             = 'S': choice corresponding to a combination method [4]
-C                    of the approaches of Enns [1] and Lin-Chiu [2,3];
-C             = 'E': choice corresponding to the stability enhanced
-C                    modified combination method of [4].
-C
-C     JOBO    CHARACTER*1
-C             Specifies the choice of frequency-weighted observability
-C             Grammian as follows:
-C             = 'S': choice corresponding to a combination method [4]
-C                    of the approaches of Enns [1] and Lin-Chiu [2,3];
-C             = 'E': choice corresponding to the stability enhanced
-C                    modified combination method of [4].
-C
-C     WEIGHT  CHARACTER*1
-C             Specifies the type of frequency weighting, as follows:
-C             = 'N':  no weightings are used (V = I, W = I);
-C             = 'L':  only left weighting V is used (W = I);
-C             = 'R':  only right weighting W is used (V = I);
-C             = 'B':  both left and right weightings V and W are used.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the state-space representation of G, i.e.,
-C             the order of the matrix A.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of columns of the matrix B and
-C             the number of rows of the matrices CW and DW.  M >= 0.
-C             M represents the dimension of the input vector of the
-C             system with the transfer-function matrix G and
-C             also the dimension of the output vector of the system
-C             with the transfer-function matrix W.
-C
-C     P       (input) INTEGER
-C             The number of rows of the matrix C and the
-C             number of columns of the matrices BV and DV.  P >= 0.
-C             P represents the dimension of the output vector of the
-C             system with the transfer-function matrix G and
-C             also the dimension of the input vector of the system
-C             with the transfer-function matrix V.
-C
-C     NV      (input) INTEGER
-C             The order of the matrix AV. Also the number of rows of
-C             the matrix BV and the number of columns of the matrix CV.
-C             NV represents the dimension of the state vector of the
-C             system with the transfer-function matrix V.  NV >= 0.
-C
-C     PV      (input) INTEGER
-C             The number of rows of the matrices CV and DV.  PV >= 0.
-C             PV represents the dimension of the output vector of the
-C             system with the transfer-function matrix V.
-C
-C     NW      (input) INTEGER
-C             The order of the matrix AW. Also the number of rows of
-C             the matrix BW and the number of columns of the matrix CW.
-C             NW represents the dimension of the state vector of the
-C             system with the transfer-function matrix W.  NW >= 0.
-C
-C     MW      (input) INTEGER
-C             The number of columns of the matrices BW and DW.  MW >= 0.
-C             MW represents the dimension of the input vector of the
-C             system with the transfer-function matrix W.
-C
-C     ALPHAC  (input) DOUBLE PRECISION
-C             Combination method parameter for defining the
-C             frequency-weighted controllability Grammian (see METHOD);
-C             ABS(ALPHAC) <= 1.
-C
-C     ALPHAO  (input) DOUBLE PRECISION
-C             Combination method parameter for defining the
-C             frequency-weighted observability Grammian (see METHOD);
-C             ABS(ALPHAO) <= 1.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,N)
-C             The leading N-by-N part of this array must
-C             contain the state matrix A (of the system with the
-C             transfer-function matrix G) in a real Schur form.
-C
-C     LDA     INTEGER
-C             The leading dimension of 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             input/state matrix B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input) DOUBLE PRECISION array, dimension (LDC,N)
-C             The leading P-by-N part of this array must contain the
-C             state/output matrix C.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     AV      (input) DOUBLE PRECISION array, dimension (LDAV,NV)
-C             If WEIGHT = 'L' or 'B', the leading NV-by-NV part of this
-C             array must contain the state matrix AV (of the system with
-C             the transfer-function matrix V) in a real Schur form.
-C             AV is not referenced if WEIGHT = 'R' or 'N'.
-C
-C     LDAV    INTEGER
-C             The leading dimension of array AV.
-C             LDAV >= MAX(1,NV), if WEIGHT = 'L' or 'B';
-C             LDAV >= 1,         if WEIGHT = 'R' or 'N'.
-C
-C     BV      (input) DOUBLE PRECISION array, dimension (LDBV,P)
-C             If WEIGHT = 'L' or 'B', the leading NV-by-P part of this
-C             array must contain the input matrix BV of the system with
-C             the transfer-function matrix V.
-C             BV is not referenced if WEIGHT = 'R' or 'N'.
-C
-C     LDBV    INTEGER
-C             The leading dimension of array BV.
-C             LDBV >= MAX(1,NV), if WEIGHT = 'L' or 'B';
-C             LDBV >= 1,         if WEIGHT = 'R' or 'N'.
-C
-C     CV      (input) DOUBLE PRECISION array, dimension (LDCV,NV)
-C             If WEIGHT = 'L' or 'B', the leading PV-by-NV part of this
-C             array must contain the output matrix CV of the system with
-C             the transfer-function matrix V.
-C             CV is not referenced if WEIGHT = 'R' or 'N'.
-C
-C     LDCV    INTEGER
-C             The leading dimension of array CV.
-C             LDCV >= MAX(1,PV), if WEIGHT = 'L' or 'B';
-C             LDCV >= 1,         if WEIGHT = 'R' or 'N'.
-C
-C     DV      (input) DOUBLE PRECISION array, dimension (LDDV,P)
-C             If WEIGHT = 'L' or 'B', the leading PV-by-P part of this
-C             array must contain the feedthrough matrix DV of the system
-C             with the transfer-function matrix V.
-C             DV is not referenced if WEIGHT = 'R' or 'N'.
-C
-C     LDDV    INTEGER
-C             The leading dimension of array DV.
-C             LDDV >= MAX(1,PV), if WEIGHT = 'L' or 'B';
-C             LDDV >= 1,         if WEIGHT = 'R' or 'N'.
-C
-C     AW      (input) DOUBLE PRECISION array, dimension (LDAW,NW)
-C             If WEIGHT = 'R' or 'B', the leading NW-by-NW part of this
-C             array must contain the state matrix AW (of the system with
-C             the transfer-function matrix W) in a real Schur form.
-C             AW is not referenced if WEIGHT = 'L' or 'N'.
-C
-C     LDAW    INTEGER
-C             The leading dimension of array AW.
-C             LDAW >= MAX(1,NW), if WEIGHT = 'R' or 'B';
-C             LDAW >= 1,         if WEIGHT = 'L' or 'N'.
-C
-C     BW      (input) DOUBLE PRECISION array, dimension (LDBW,MW)
-C             If WEIGHT = 'R' or 'B', the leading NW-by-MW part of this
-C             array must contain the input matrix BW of the system with
-C             the transfer-function matrix W.
-C             BW is not referenced if WEIGHT = 'L' or 'N'.
-C
-C     LDBW    INTEGER
-C             The leading dimension of array BW.
-C             LDBW >= MAX(1,NW), if WEIGHT = 'R' or 'B';
-C             LDBW >= 1,         if WEIGHT = 'L' or 'N'.
-C
-C     CW      (input) DOUBLE PRECISION array, dimension (LDCW,NW)
-C             If WEIGHT = 'R' or 'B', the leading M-by-NW part of this
-C             array must contain the output matrix CW of the system with
-C             the transfer-function matrix W.
-C             CW is not referenced if WEIGHT = 'L' or 'N'.
-C
-C     LDCW    INTEGER
-C             The leading dimension of array CW.
-C             LDCW >= MAX(1,M), if WEIGHT = 'R' or 'B';
-C             LDCW >= 1,        if WEIGHT = 'L' or 'N'.
-C
-C     DW      (input) DOUBLE PRECISION array, dimension (LDDW,MW)
-C             If WEIGHT = 'R' or 'B', the leading M-by-MW part of this
-C             array must contain the feedthrough matrix DW of the system
-C             with the transfer-function matrix W.
-C             DW is not referenced if WEIGHT = 'L' or 'N'.
-C
-C     LDDW    INTEGER
-C             The leading dimension of array DW.
-C             LDDW >= MAX(1,M), if WEIGHT = 'R' or 'B';
-C             LDDW >= 1,        if WEIGHT = 'L' or 'N'.
-C
-C     SCALEC  (output) DOUBLE PRECISION
-C             Scaling factor for the controllability Grammian in (1)
-C             or (3). See METHOD.
-C
-C     SCALEO  (output) DOUBLE PRECISION
-C             Scaling factor for the observability Grammian in (2)
-C             or (4). See METHOD.
-C
-C     S       (output) DOUBLE PRECISION array, dimension (LDS,N)
-C             The leading N-by-N upper triangular part of this array
-C             contains the Cholesky factor S of the frequency-weighted
-C             cotrollability Grammian P = S*S'. See METHOD.
-C
-C     LDS     INTEGER
-C             The leading dimension of array S.  LDS >= MAX(1,N).
-C
-C     R       (output) DOUBLE PRECISION array, dimension (LDR,N)
-C             The leading N-by-N upper triangular part of this array
-C             contains the Cholesky factor R of the frequency-weighted
-C             observability Grammian Q = R'*R. See METHOD.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,N).
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX( 1, LLEFT, LRIGHT ),
-C             where
-C             LLEFT  = (N+NV)*(N+NV+MAX(N+NV,PV)+5)
-C                              if WEIGHT = 'L' or 'B' and PV > 0;
-C             LLEFT  = N*(P+5) if WEIGHT = 'R' or 'N' or  PV = 0;
-C             LRIGHT = (N+NW)*(N+NW+MAX(N+NW,MW)+5)
-C                              if WEIGHT = 'R' or 'B' and MW > 0;
-C             LRIGHT = N*(M+5) if WEIGHT = 'L' or 'N' or  MW = 0.
-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 state matrices A and/or AV are not stable or
-C                   not in a real Schur form;
-C             = 2:  if the state matrices A and/or AW are not stable or
-C                   not in a real Schur form;
-C             = 3:  eigenvalues computation failure.
-C
-C     METHOD
-C
-C     Let Pi = Si*Si' and Qo = Ro'*Ro be the Cholesky factored
-C     controllability and observability Grammians satisfying
-C     in the continuous-time case
-C
-C            Ai*Pi + Pi*Ai' +  scalec^2*Bi*Bi' = 0,       (1)
-C
-C            Ao'*Qo + Qo*Ao +  scaleo^2*Co'*Co = 0,       (2)
-C
-C     and in the discrete-time case
-C
-C            Ai*Pi*Ai' - Pi +  scalec^2*Bi*Bi' = 0,       (3)
-C
-C            Ao'*Qo*Ao - Qo +  scaleo^2*Co'*Co = 0,       (4)
-C
-C     where
-C
-C           Ai = ( A  B*Cw ) ,   Bi = ( B*Dw ) ,
-C                ( 0   Aw  )          (  Bw  )
-C
-C           Ao = (  A   0  ) ,   Co = ( Dv*C  Cv ) .
-C                ( Bv*C Av )
-C
-C     Consider the partitioned Grammians
-C
-C           Pi = ( P11  P12 )   and    Qo = ( Q11  Q12 ) ,
-C                ( P12' P22 )               ( Q12' Q22 )
-C
-C     where P11 and Q11 are the leading N-by-N parts of Pi and Qo,
-C     respectively, and let P0 and Q0 be non-negative definite matrices
-C     defined in the combination method [4]
-C                                        -1
-C            P0 = P11 - ALPHAC**2*P12*P22 *P21 ,
-C                                        -1
-C            Q0 = Q11 - ALPHAO**2*Q12*Q22 *Q21.
-C
-C     The frequency-weighted controllability and observability
-C     Grammians, P and Q, respectively, are defined as follows:
-C     P = P0 if JOBC = 'S' (standard combination method [4]);
-C     P = P1 >= P0 if JOBC = 'E', where P1 is the controllability
-C     Grammian defined to enforce stability for a modified combination
-C     method of [4];
-C     Q = Q0 if JOBO = 'S' (standard combination method [4]);
-C     Q = Q1 >= Q0 if JOBO = 'E', where Q1 is the observability
-C     Grammian defined to enforce stability for a modified combination
-C     method of [4].
-C
-C     If JOBC = JOBO = 'S' and ALPHAC = ALPHAO = 0, the choice of
-C     Grammians corresponds to the method of Enns [1], while if
-C     ALPHAC = ALPHAO = 1, the choice of Grammians corresponds to the
-C     method of Lin and Chiu [2,3].
-C
-C     The routine computes directly the Cholesky factors S and R
-C     such that P = S*S' and Q = R'*R according to formulas
-C     developed in [4]. No matrix inversions are involved.
-C
-C     REFERENCES
-C
-C     [1] Enns, D.
-C         Model reduction with balanced realizations: An error bound
-C         and a frequency weighted generalization.
-C         Proc. CDC, Las Vegas, pp. 127-132, 1984.
-C
-C     [2] Lin, C.-A. and Chiu, T.-Y.
-C         Model reduction via frequency-weighted balanced realization.
-C         Control Theory and Advanced Technology, vol. 8,
-C         pp. 341-351, 1992.
-C
-C     [3] Sreeram, V., Anderson, B.D.O and Madievski, A.G.
-C         New results on frequency weighted balanced reduction
-C         technique.
-C         Proc. ACC, Seattle, Washington, pp. 4004-4009, 1995.
-C
-C     [4] Varga, A. and Anderson, B.D.O.
-C         Square-root balancing-free methods for the frequency-weighted
-C         balancing related model reduction.
-C         (report in preparation)
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, August 2000.
-C     D. Sima, University of Bucharest, August 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 2000.
-C
-C     REVISIONS
-C
-C     A. Varga, Australian National University, Canberra, November 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Dec. 2000.
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, August 2001.
-C
-C     KEYWORDS
-C
-C     Frequency weighting, model reduction, multivariable system,
-C     state-space model, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION ZERO, ONE
-      PARAMETER        ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER        DICO, JOBC, JOBO, WEIGHT
-      INTEGER          INFO, LDA, LDAV, LDAW, LDB, LDBV, LDBW,
-     $                 LDC, LDCV, LDCW, LDDV, LDDW, LDR, LDS, LDWORK,
-     $                 M, MW, N, NV, NW, P, PV
-      DOUBLE PRECISION ALPHAC, ALPHAO, SCALEC, SCALEO
-C     .. Array Arguments ..
-      DOUBLE PRECISION A(LDA,*), AV(LDAV,*), AW(LDAW,*),
-     $                 B(LDB,*), BV(LDBV,*), BW(LDBW,*),
-     $                 C(LDC,*), CV(LDCV,*), CW(LDCW,*),
-     $                           DV(LDDV,*), DW(LDDW,*),
-     $                 DWORK(*), R(LDR,*),   S(LDS,*)
-C     .. Local Scalars ..
-      LOGICAL          DISCR, FRWGHT, LEFTW, RIGHTW
-      INTEGER          I, IERR, J, KAW, KTAU, KU, KW, LDU, LW, MBBAR,
-     $                 NNV, NNW, PCBAR
-      DOUBLE PRECISION T, TOL, WORK
-C     .. Local Arrays ..
-      DOUBLE PRECISION DUM(1)
-C     .. External Functions ..
-      LOGICAL          LSAME
-      DOUBLE PRECISION DLAMCH
-      EXTERNAL         DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL         DCOPY, DGEMM, DLACPY, DLASET, DSCAL, DSYEV,
-     $                 MB01WD, MB04ND, MB04OD, SB03OU, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC        ABS, DBLE, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      DISCR  = LSAME( DICO,   'D' )
-      LEFTW  = LSAME( WEIGHT, 'L' ) .OR. LSAME( WEIGHT, 'B' )
-      RIGHTW = LSAME( WEIGHT, 'R' ) .OR. LSAME( WEIGHT, 'B' )
-      FRWGHT = LEFTW .OR. RIGHTW
-C
-      INFO = 0
-      LW   = 1
-      NNV  = N + NV
-      NNW  = N + NW
-      IF( LEFTW .AND. PV.GT.0 ) THEN
-         LW = MAX( LW, NNV*( NNV + MAX( NNV, PV ) + 5 ) )
-      ELSE
-         LW = MAX( LW, N*( P + 5 ) )
-      END IF
-      IF( RIGHTW .AND. MW.GT.0 ) THEN
-         LW = MAX( LW, NNW*( NNW + MAX( NNW, MW ) + 5 ) )
-      ELSE
-         LW = MAX( LW, N*( M + 5 ) )
-      END IF
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( LSAME( JOBC, 'S' ) .OR. LSAME( JOBC, 'E' ) ) )
-     $     THEN
-         INFO = -2
-      ELSE IF( .NOT.( LSAME( JOBO, 'S' ) .OR. LSAME( JOBO, 'E' ) ) )
-     $     THEN
-         INFO = -3
-      ELSE IF( .NOT.( FRWGHT .OR. LSAME( WEIGHT, 'N' ) ) ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( NV.LT.0 ) THEN
-         INFO = -8
-      ELSE IF( PV.LT.0 ) THEN
-         INFO = -9
-      ELSE IF( NW.LT.0 ) THEN
-         INFO = -10
-      ELSE IF( MW.LT.0 ) THEN
-         INFO = -11
-      ELSE IF( ABS( ALPHAC ).GT.ONE  ) THEN
-         INFO = -12
-      ELSE IF( ABS( ALPHAO ).GT.ONE  ) THEN
-         INFO = -13
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -15
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -17
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -19
-      ELSE IF( LDAV.LT.1 .OR. ( LEFTW  .AND. LDAV.LT.NV ) ) THEN
-         INFO = -21
-      ELSE IF( LDBV.LT.1 .OR. ( LEFTW  .AND. LDBV.LT.NV ) ) THEN
-         INFO = -23
-      ELSE IF( LDCV.LT.1 .OR. ( LEFTW  .AND. LDCV.LT.PV ) ) THEN
-         INFO = -25
-      ELSE IF( LDDV.LT.1 .OR. ( LEFTW  .AND. LDDV.LT.PV ) ) THEN
-         INFO = -27
-      ELSE IF( LDAW.LT.1 .OR. ( RIGHTW .AND. LDAW.LT.NW ) ) THEN
-         INFO = -29
-      ELSE IF( LDBW.LT.1 .OR. ( RIGHTW .AND. LDBW.LT.NW ) ) THEN
-         INFO = -31
-      ELSE IF( LDCW.LT.1 .OR. ( RIGHTW .AND. LDCW.LT.M  ) ) THEN
-         INFO = -33
-      ELSE IF( LDDW.LT.1 .OR. ( RIGHTW .AND. LDDW.LT.M  ) ) THEN
-         INFO = -35
-      ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
-         INFO = -39
-      ELSE IF( LDR.LT.MAX( 1, N ) ) THEN
-         INFO = -41
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -43
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09IY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      SCALEC = ONE
-      SCALEO = ONE
-      IF( MIN( N, M, P ).EQ.0 ) THEN
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      WORK = 1
-      IF( LEFTW .AND. PV.GT.0 ) THEN
-C
-C        Build the extended permuted matrices
-C
-C           Ao = ( Av  Bv*C ) ,   Co = ( Cv Dv*C ) .
-C                ( 0     A  )
-C
-         KAW = 1
-         KU  = KAW + NNV*NNV
-         LDU = MAX( NNV, PV )
-         CALL DLACPY( 'Full', NV, NV, AV, LDAV, DWORK(KAW), NNV )
-         CALL DLASET( 'Full', N, NV, ZERO, ZERO, DWORK(KAW+NV), NNV )
-         CALL DGEMM( 'No-transpose', 'No-transpose', NV, N, P, ONE,
-     $               BV, LDBV, C, LDC, ZERO, DWORK(KAW+NNV*NV), NNV )
-         CALL DLACPY( 'Full', N, N, A, LDA, DWORK(KAW+NNV*NV+NV), NNV )
-C
-         CALL DLACPY( 'Full', PV, NV, CV, LDCV, DWORK(KU), LDU  )
-         CALL DGEMM( 'No-transpose', 'No-transpose', PV, N, P, ONE,
-     $               DV, LDDV, C, LDC, ZERO, DWORK(KU+LDU*NV), LDU )
-C
-C        Solve for the Cholesky factor Ro of Qo, Qo = Ro'*Ro,
-C        the continuous-time Lyapunov equation (if DICO = 'C')
-C
-C            Ao'*Qo + Qo*Ao  +  scaleo^2*Co'*Co = 0,
-C
-C        or the discrete-time Lyapunov equation (if DICO = 'D')
-C
-C            Ao'*Qo*Ao - Qo +  scaleo^2*Co'*Co = 0.
-C
-C        Workspace:  need   (N+NV)*(N+NV+MAX(N+NV,PV)+5);
-C                           prefer larger.
-C
-         KTAU = KU + LDU*NNV
-         KW   = KTAU + NNV
-C
-         CALL SB03OU( DISCR, .FALSE., NNV, PV, DWORK(KAW), NNV,
-     $                DWORK(KU), LDU, DWORK(KTAU), DWORK(KU), LDU,
-     $                SCALEO, DWORK(KW), LDWORK-KW+1, IERR )
-C
-         IF( IERR.NE.0 ) THEN
-            INFO = 1
-            RETURN
-         END IF
-         WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-C
-C        Partition Ro as Ro = ( R11 R12 ) and compute R such that
-C                             (  0  R22 )
-C
-C        R'*R = R22'*R22 + (1-ALPHAO**2)*R12'*R12.
-C
-         KW = KU + LDU*NV + NV
-         CALL DLACPY( 'Upper', N, N, DWORK(KW), LDU, R, LDR )
-         IF( ALPHAO.NE.ZERO ) THEN
-            T = SQRT( ONE - ALPHAO*ALPHAO )
-            DO 10 J = KU + LDU*NV, KU + LDU*(NNV-1), LDU
-               CALL DSCAL( NV, T, DWORK(J), 1 )
-   10       CONTINUE
-         END IF
-         IF( ALPHAO.LT.ONE .AND. NV.GT.0 ) THEN
-            KTAU = 1
-            CALL MB04OD( 'Full', N, 0, NV, R, LDR, DWORK(KU+LDU*NV),
-     $                   LDU, DUM, 1, DUM, 1, DWORK(KTAU), DWORK(KW) )
-C
-            DO 30 J = 1, N
-               DWORK(J) = R(J,J)
-               DO 20 I = 1, J
-                  IF ( DWORK(I).LT.ZERO ) R(I,J) = -R(I,J)
-   20          CONTINUE
-   30       CONTINUE
-C
-         END IF
-C
-         IF( LSAME( JOBO, 'E' ) .AND. ALPHAO.LT.ONE ) THEN
-C
-C           Form Y = -A'*(R'*R)-(R'*R)*A if DICO = 'C', or
-C                Y = -A'*(R'*R)*A+(R'*R) if DICO = 'D'.
-C
-            CALL DLACPY( 'Upper', N, N, R, LDR, DWORK(KU), N )
-            CALL MB01WD( DICO, 'Upper', 'No-transpose', 'Hessenberg', N,
-     $                   -ONE, ZERO, R, LDR, DWORK(KAW+NNV*NV+NV), NNV,
-     $                   DWORK(KU), N, IERR )
-C
-C           Compute the eigendecomposition of Y as Y = Z*Sigma*Z'.
-C
-            KU = N + 1
-            CALL DSYEV( 'Vectors', 'Upper', N, R, LDR, DWORK, DWORK(KU),
-     $                  LDWORK-N, IERR )
-            IF( IERR.GT.0 ) THEN
-               INFO = 3
-               RETURN
-            END IF
-            WORK = MAX( WORK, DWORK(KU) + DBLE( N ) )
-C
-C           Partition Sigma = (Sigma1,Sigma2), such that
-C           Sigma1 <= 0, Sigma2 > 0.
-C           Partition correspondingly Z = [Z1 Z2].
-C
-            TOL = MAX( ABS( DWORK(1) ), ABS( DWORK(N) ) )
-     $            * DLAMCH( 'Epsilon')
-C                _
-C           Form C = [ sqrt(Sigma2)*Z2' ]
-C
-            PCBAR = 0
-            DO 40 J = 1, N
-               IF( DWORK(J).GT.TOL ) THEN
-                  CALL DSCAL( N, SQRT( DWORK(J) ), R(1,J), 1 )
-                  CALL DCOPY( N, R(1,J), 1, DWORK(KU+PCBAR), N )
-                  PCBAR = PCBAR + 1
-               END IF
-   40       CONTINUE
-C
-C           Solve for the Cholesky factor R of Q, Q = R'*R,
-C           the continuous-time Lyapunov equation (if DICO = 'C')
-C                                      _  _
-C                   A'*Q + Q*A  +  t^2*C'*C = 0,
-C
-C           or the discrete-time Lyapunov equation (if DICO = 'D')
-C                                      _  _
-C                   A'*Q*A - Q  +  t^2*C'*C = 0.
-C
-C           Workspace:  need   N*(N + 6);
-C                              prefer larger.
-C
-            KTAU = KU + N*N
-            KW   = KTAU + N
-C
-            CALL SB03OU( DISCR, .FALSE., N, PCBAR, A, LDA, DWORK(KU), N,
-     $                   DWORK(KTAU), R, LDR, T, DWORK(KW), LDWORK-KW+1,
-     $                   IERR )
-            IF( IERR.NE.0 ) THEN
-               INFO = 1
-               RETURN
-            END IF
-            SCALEO = SCALEO*T
-            WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-         END IF
-C
-      ELSE
-C
-C        Solve for the Cholesky factor R of Q, Q = R'*R,
-C        the continuous-time Lyapunov equation (if DICO = 'C')
-C
-C            A'*Q + Q*A  +  scaleo^2*C'*C = 0,
-C
-C        or the discrete-time Lyapunov equation (if DICO = 'D')
-C
-C            A'*Q*A - Q +  scaleo^2*C'*C = 0.
-C
-C        Workspace:  need   N*(P + 5);
-C                           prefer larger.
-C
-         KU   = 1
-         KTAU = KU + P*N
-         KW   = KTAU + N
-C
-         CALL DLACPY( 'Full', P, N, C, LDC, DWORK(KU), P )
-         CALL SB03OU( DISCR, .FALSE., N, P, A, LDA, DWORK(KU), P,
-     $                DWORK(KTAU), R, LDR, SCALEO, DWORK(KW),
-     $                LDWORK-KW+1, IERR )
-         IF( IERR.NE.0 ) THEN
-            INFO = 1
-            RETURN
-         END IF
-         WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-      END IF
-C
-      IF( RIGHTW .AND. MW.GT.0 ) THEN
-C
-C        Build the extended matrices
-C
-C           Ai = ( A  B*Cw ) ,   Bi = ( B*Dw ) .
-C                ( 0   Aw  )          (  Bw  )
-C
-         KAW = 1
-         KU  = KAW + NNW*NNW
-         CALL DLACPY( 'Full', N, N, A, LDA, DWORK(KAW), NNW )
-         CALL DLASET( 'Full', NW, N, ZERO, ZERO, DWORK(KAW+N), NNW )
-         CALL DGEMM( 'No-transpose', 'No-transpose', N, NW, M, ONE,
-     $               B, LDB, CW, LDCW, ZERO, DWORK(KAW+NNW*N), NNW )
-         CALL DLACPY( 'Full', NW, NW, AW, LDAW,
-     $                DWORK(KAW+NNW*N+N), NNW )
-C
-         CALL DGEMM( 'No-transpose', 'No-transpose', N, MW, M, ONE,
-     $               B, LDB, DW, LDDW, ZERO, DWORK(KU), NNW  )
-         CALL DLACPY( 'Full', NW, MW, BW, LDBW, DWORK(KU+N), NNW )
-C
-C        Solve for the Cholesky factor Si of Pi, Pi = Si*Si',
-C        the continuous-time Lyapunov equation (if DICO = 'C')
-C
-C            Ai*Pi + Pi*Ai' +  scalec^2*Bi*Bi' = 0,
-C
-C        or the discrete-time Lyapunov equation (if DICO = 'D')
-C
-C            Ai*Pi*Ai' - Pi +  scalec^2*Bi*Bi' = 0.
-C
-C        Workspace:  need   (N+NW)*(N+NW+MAX(N+NW,MW)+5);
-C                           prefer larger.
-C
-         KTAU = KU + NNW*MAX( NNW, MW )
-         KW   = KTAU + NNW
-C
-         CALL SB03OU( DISCR, .TRUE., NNW, MW, DWORK(KAW), NNW,
-     $                DWORK(KU), NNW, DWORK(KTAU), DWORK(KU), NNW,
-     $                SCALEC, DWORK(KW), LDWORK-KW+1, IERR )
-C
-         IF( IERR.NE.0 ) THEN
-            INFO = 2
-            RETURN
-         END IF
-         WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-C
-C        Partition Si as Si = ( S11 S12 ) and compute S such that
-C                             (  0  S22 )
-C
-C        S*S' = S11*S11' + (1-ALPHAC**2)*S12*S12'.
-C
-         CALL DLACPY( 'Upper', N, N, DWORK(KU), NNW, S, LDS )
-         IF( ALPHAC.NE.ZERO ) THEN
-            T = SQRT( ONE - ALPHAC*ALPHAC )
-            DO 50 J = KU + NNW*N, KU + NNW*(NNW-1), NNW
-               CALL DSCAL( N, T, DWORK(J), 1 )
-   50       CONTINUE
-         END IF
-         IF( ALPHAC.LT.ONE .AND. NW.GT.0 ) THEN
-            KTAU = N*NNW + 1
-            KW   = KTAU  + N
-            CALL MB04ND( 'Full', N, 0, NW, S, LDS, DWORK(KU+NNW*N), NNW,
-     $                   DUM, 1, DUM, 1, DWORK(KTAU), DWORK(KW) )
-C
-            DO 70 J = 1, N
-               IF ( S(J,J).LT.ZERO ) THEN
-                  DO 60 I = 1, J
-                     S(I,J) = -S(I,J)
-   60             CONTINUE
-               END IF
-   70       CONTINUE
-         END IF
-C
-         IF( LSAME( JOBC, 'E' ) .AND. ALPHAC.LT.ONE ) THEN
-C
-C           Form X = -A*(S*S')-(S*S')*A' if DICO = 'C', or
-C                X = -A*(S*S')*A'+(S*S') if DICO = 'D'.
-C
-            CALL DLACPY( 'Upper', N, N, S, LDS, DWORK(KU), N )
-            CALL MB01WD( DICO, 'Upper', 'Transpose', 'Hessenberg', N,
-     $                   -ONE, ZERO, S, LDS, DWORK(KAW), NNW, DWORK(KU),
-     $                   N, IERR )
-C
-C           Compute the eigendecomposition of X as X = Z*Sigma*Z'.
-C
-            KU = N + 1
-            CALL DSYEV( 'Vectors', 'Upper', N, S, LDS, DWORK, DWORK(KU),
-     $                  LDWORK-N, IERR )
-            IF( IERR.GT.0 ) THEN
-               INFO = 3
-               RETURN
-            END IF
-            WORK = MAX( WORK, DWORK(KU) + DBLE( N ) )
-C
-C           Partition Sigma = (Sigma1,Sigma2), such that
-C           Sigma1 =< 0, Sigma2 > 0.
-C           Partition correspondingly Z = [Z1 Z2].
-C
-            TOL = MAX( ABS( DWORK(1) ), ABS( DWORK(N) ) )
-     $            * DLAMCH( 'Epsilon')
-C                _
-C           Form B = [ Z2*sqrt(Sigma2) ]
-C
-            MBBAR = 0
-            I = KU
-            DO 80 J = 1, N
-               IF( DWORK(J).GT.TOL ) THEN
-                  MBBAR = MBBAR + 1
-                  CALL DSCAL( N, SQRT( DWORK(J) ), S(1,J), 1 )
-                  CALL DCOPY( N, S(1,J), 1, DWORK(I), 1 )
-                  I = I + N
-               END IF
-   80       CONTINUE
-C
-C           Solve for the Cholesky factor S of P, P = S*S',
-C           the continuous-time Lyapunov equation (if DICO = 'C')
-C                                      _ _
-C                   A*P + P*A'  +  t^2*B*B' = 0,
-C
-C           or the discrete-time Lyapunov equation (if DICO = 'D')
-C                                      _ _
-C                   A*P*A' - P  +  t^2*B*B' = 0.
-C
-C           Workspace:  need   maximum N*(N + 6);
-C                              prefer larger.
-C
-            KTAU = KU + MBBAR*N
-            KW   = KTAU + N
-C
-            CALL SB03OU( DISCR, .TRUE., N, MBBAR, A, LDA, DWORK(KU), N,
-     $                   DWORK(KTAU), S, LDS, T, DWORK(KW), LDWORK-KW+1,
-     $                   IERR )
-            IF( IERR.NE.0 ) THEN
-               INFO = 2
-               RETURN
-            END IF
-            SCALEC = SCALEC*T
-            WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-         END IF
-C
-      ELSE
-C
-C        Solve for the Cholesky factor S of P, P = S*S',
-C        the continuous-time Lyapunov equation (if DICO = 'C')
-C
-C            A*P + P*A' +  scalec^2*B*B' = 0,
-C
-C        or the discrete-time Lyapunov equation (if DICO = 'D')
-C
-C            A*P*A' - P +  scalec^2*B*B' = 0.
-C
-C        Workspace:  need   N*(M+5);
-C                           prefer larger.
-C
-         KU   = 1
-         KTAU = KU + N*M
-         KW   = KTAU + N
-C
-         CALL DLACPY( 'Full', N, M, B, LDB, DWORK(KU), N )
-         CALL SB03OU( DISCR, .TRUE., N, M, A, LDA, DWORK(KU), N,
-     $                DWORK(KTAU), S, LDS, SCALEC, DWORK(KW),
-     $                LDWORK-KW+1, IERR )
-         IF( IERR.NE.0 ) THEN
-            INFO = 2
-            RETURN
-         END IF
-         WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-      END IF
-C
-C     Save optimal workspace.
-C
-      DWORK(1) = WORK
-C
-      RETURN
-C *** Last line of AB09IY ***
-      END
--- a/extra/control-devel/src/AB09JD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1482 +0,0 @@
-      SUBROUTINE AB09JD( JOBV, JOBW, JOBINV, DICO, EQUIL, ORDSEL,
-     $                   N, NV, NW, M, P, NR, ALPHA, A, LDA, B, LDB,
-     $                   C, LDC, D, LDD, AV, LDAV, BV, LDBV,
-     $                   CV, LDCV, DV, LDDV, AW, LDAW, BW, LDBW,
-     $                   CW, LDCW, DW, LDDW, NS, HSV, TOL1, TOL2,
-     $                   IWORK, DWORK, LDWORK, IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order model (Ar,Br,Cr,Dr) for an original
-C     state-space representation (A,B,C,D) by using the frequency
-C     weighted optimal Hankel-norm approximation method.
-C     The Hankel norm of the weighted error
-C
-C           op(V)*(G-Gr)*op(W)
-C
-C     is minimized, where G and Gr are the transfer-function matrices
-C     of the original and reduced systems, respectively, V and W are
-C     invertible transfer-function matrices representing the left and
-C     right frequency weights, and op(X) denotes X, inv(X), conj(X) or
-C     conj(inv(X)). V and W are specified by their state space
-C     realizations (AV,BV,CV,DV) and (AW,BW,CW,DW), respectively.
-C     When minimizing ||V*(G-Gr)*W||, V and W must be antistable.
-C     When minimizing inv(V)*(G-Gr)*inv(W), V and W must have only
-C     antistable zeros.
-C     When minimizing conj(V)*(G-Gr)*conj(W), V and W must be stable.
-C     When minimizing conj(inv(V))*(G-Gr)*conj(inv(W)), V and W must
-C     be minimum-phase.
-C     If the original system is unstable, then the frequency weighted
-C     Hankel-norm approximation is computed only for the
-C     ALPHA-stable part of the system.
-C
-C     For a transfer-function matrix G, conj(G) denotes the conjugate
-C     of G given by G'(-s) for a continuous-time system or G'(1/z)
-C     for a discrete-time system.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBV    CHARACTER*1
-C             Specifies the left frequency-weighting as follows:
-C             = 'N':  V = I;
-C             = 'V':  op(V) = V;
-C             = 'I':  op(V) = inv(V);
-C             = 'C':  op(V) = conj(V);
-C             = 'R':  op(V) = conj(inv(V)).
-C
-C     JOBW    CHARACTER*1
-C             Specifies the right frequency-weighting as follows:
-C             = 'N':  W = I;
-C             = 'W':  op(W) = W;
-C             = 'I':  op(W) = inv(W);
-C             = 'C':  op(W) = conj(W);
-C             = 'R':  op(W) = conj(inv(W)).
-C
-C     JOBINV  CHARACTER*1
-C             Specifies the computational approach to be used as
-C             follows:
-C             = 'N':  use the inverse free descriptor system approach;
-C             = 'I':  use the inversion based standard approach;
-C             = 'A':  switch automatically to the inverse free
-C                     descriptor approach in case of badly conditioned
-C                     feedthrough matrices in V or W (see METHOD).
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     EQUIL   CHARACTER*1
-C             Specifies whether the user wishes to preliminarily
-C             equilibrate the triplet (A,B,C) as follows:
-C             = 'S':  perform equilibration (scaling);
-C             = 'N':  do not perform equilibration.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting order NR is fixed;
-C             = 'A':  the resulting order NR is automatically determined
-C                     on basis of the given tolerance TOL1.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation,
-C             i.e., the order of the matrix A.  N >= 0.
-C
-C     NV      (input) INTEGER
-C             The order of the realization of the left frequency
-C             weighting V, i.e., the order of the matrix AV.  NV >= 0.
-C
-C     NW      (input) INTEGER
-C             The order of the realization of the right frequency
-C             weighting W, i.e., the order of the matrix AW.  NW >= 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     NR      (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NR is the desired order of
-C             the resulting reduced order system.  0 <= NR <= N.
-C             On exit, if INFO = 0, NR is the order of the resulting
-C             reduced order model. For a system with NU ALPHA-unstable
-C             eigenvalues and NS ALPHA-stable eigenvalues (NU+NS = N),
-C             NR is set as follows: if ORDSEL = 'F', NR is equal to
-C             NU+MIN(MAX(0,NR-NU-KR+1),NMIN), where KR is the
-C             multiplicity of the Hankel singular value HSV(NR-NU+1),
-C             NR is the desired order on entry, and NMIN is the order
-C             of a minimal realization of the ALPHA-stable part of the
-C             given system; NMIN is determined as the number of Hankel
-C             singular values greater than NS*EPS*HNORM(As,Bs,Cs), where
-C             EPS is the machine precision (see LAPACK Library Routine
-C             DLAMCH) and HNORM(As,Bs,Cs) is the Hankel norm of the
-C             ALPHA-stable part of the weighted system (computed in
-C             HSV(1));
-C             if ORDSEL = 'A', NR is the sum of NU and the number of
-C             Hankel singular values greater than
-C             MAX(TOL1,NS*EPS*HNORM(As,Bs,Cs)).
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             Specifies the ALPHA-stability boundary for the eigenvalues
-C             of the state dynamics matrix A. For a continuous-time
-C             system (DICO = 'C'), ALPHA <= 0 is the boundary value for
-C             the real parts of eigenvalues, while for a discrete-time
-C             system (DICO = 'D'), 0 <= ALPHA <= 1 represents the
-C             boundary value for the moduli of eigenvalues.
-C             The ALPHA-stability domain does not include the boundary.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A.
-C             On exit, if INFO = 0, the leading NR-by-NR part of this
-C             array contains the state dynamics matrix Ar of the
-C             reduced order system in a real Schur form.
-C             The resulting A has a block-diagonal form with two blocks.
-C             For a system with NU ALPHA-unstable eigenvalues and
-C             NS ALPHA-stable eigenvalues (NU+NS = N), the leading
-C             NU-by-NU block contains the unreduced part of A
-C             corresponding to ALPHA-unstable eigenvalues.
-C             The trailing (NR+NS-N)-by-(NR+NS-N) block contains
-C             the reduced part of A corresponding to ALPHA-stable
-C             eigenvalues.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, if INFO = 0, the leading NR-by-M part of this
-C             array contains the input/state matrix Br of the reduced
-C             order system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, if INFO = 0, the leading P-by-NR part of this
-C             array contains the state/output matrix Cr of the reduced
-C             order system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the original input/output matrix D.
-C             On exit, if INFO = 0, the leading P-by-M part of this
-C             array contains the input/output matrix Dr of the reduced
-C             order system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     AV      (input/output) DOUBLE PRECISION array, dimension (LDAV,NV)
-C             On entry, if JOBV <> 'N', the leading NV-by-NV part of
-C             this array must contain the state matrix AV of a state
-C             space realization of the left frequency weighting V.
-C             On exit, if JOBV <> 'N', and INFO = 0, the leading
-C             NV-by-NV part of this array contains the real Schur form
-C             of AV.
-C             AV is not referenced if JOBV = 'N'.
-C
-C     LDAV    INTEGER
-C             The leading dimension of the array AV.
-C             LDAV >= MAX(1,NV), if JOBV <> 'N';
-C             LDAV >= 1,         if JOBV =  'N'.
-C
-C     BV      (input/output) DOUBLE PRECISION array, dimension (LDBV,P)
-C             On entry, if JOBV <> 'N', the leading NV-by-P part of
-C             this array must contain the input matrix BV of a state
-C             space realization of the left frequency weighting V.
-C             On exit, if JOBV <> 'N', and INFO = 0, the leading
-C             NV-by-P part of this array contains the transformed
-C             input matrix BV corresponding to the transformed AV.
-C             BV is not referenced if JOBV = 'N'.
-C
-C     LDBV    INTEGER
-C             The leading dimension of the array BV.
-C             LDBV >= MAX(1,NV), if JOBV <> 'N';
-C             LDBV >= 1,         if JOBV =  'N'.
-C
-C     CV      (input/output) DOUBLE PRECISION array, dimension (LDCV,NV)
-C             On entry, if JOBV <> 'N', the leading P-by-NV part of
-C             this array must contain the output matrix CV of a state
-C             space realization of the left frequency weighting V.
-C             On exit, if JOBV <> 'N', and INFO = 0, the leading
-C             P-by-NV part of this array contains the transformed output
-C             matrix CV corresponding to the transformed AV.
-C             CV is not referenced if JOBV = 'N'.
-C
-C     LDCV    INTEGER
-C             The leading dimension of the array CV.
-C             LDCV >= MAX(1,P), if JOBV <> 'N';
-C             LDCV >= 1,        if JOBV =  'N'.
-C
-C     DV      (input) DOUBLE PRECISION array, dimension (LDDV,P)
-C             If JOBV <> 'N', the leading P-by-P part of this array
-C             must contain the feedthrough matrix DV of a state space
-C             realization of the left frequency weighting V.
-C             DV is not referenced if JOBV = 'N'.
-C
-C     LDDV    INTEGER
-C             The leading dimension of the array DV.
-C             LDDV >= MAX(1,P), if JOBV <> 'N';
-C             LDDV >= 1,        if JOBV =  'N'.
-C
-C     AW      (input/output) DOUBLE PRECISION array, dimension (LDAW,NW)
-C             On entry, if JOBW <> 'N', the leading NW-by-NW part of
-C             this array must contain the state matrix AW of a state
-C             space realization of the right frequency weighting W.
-C             On exit, if JOBW <> 'N', and INFO = 0, the leading
-C             NW-by-NW part of this array contains the real Schur form
-C             of AW.
-C             AW is not referenced if JOBW = 'N'.
-C
-C     LDAW    INTEGER
-C             The leading dimension of the array AW.
-C             LDAW >= MAX(1,NW), if JOBW <> 'N';
-C             LDAW >= 1,         if JOBW =  'N'.
-C
-C     BW      (input/output) DOUBLE PRECISION array, dimension (LDBW,M)
-C             On entry, if JOBW <> 'N', the leading NW-by-M part of
-C             this array must contain the input matrix BW of a state
-C             space realization of the right frequency weighting W.
-C             On exit, if JOBW <> 'N', and INFO = 0, the leading
-C             NW-by-M part of this array contains the transformed
-C             input matrix BW corresponding to the transformed AW.
-C             BW is not referenced if JOBW = 'N'.
-C
-C     LDBW    INTEGER
-C             The leading dimension of the array BW.
-C             LDBW >= MAX(1,NW), if JOBW <> 'N';
-C             LDBW >= 1,         if JOBW =  'N'.
-C
-C     CW      (input/output) DOUBLE PRECISION array, dimension (LDCW,NW)
-C             On entry, if JOBW <> 'N', the leading M-by-NW part of
-C             this array must contain the output matrix CW of a state
-C             space realization of the right frequency weighting W.
-C             On exit, if JOBW <> 'N', and INFO = 0, the leading
-C             M-by-NW part of this array contains the transformed output
-C             matrix CW corresponding to the transformed AW.
-C             CW is not referenced if JOBW = 'N'.
-C
-C     LDCW    INTEGER
-C             The leading dimension of the array CW.
-C             LDCW >= MAX(1,M), if JOBW <> 'N';
-C             LDCW >= 1,        if JOBW =  'N'.
-C
-C     DW      (input) DOUBLE PRECISION array, dimension (LDDW,M)
-C             If JOBW <> 'N', the leading M-by-M part of this array
-C             must contain the feedthrough matrix DW of a state space
-C             realization of the right frequency weighting W.
-C             DW is not referenced if JOBW = 'N'.
-C
-C     LDDW    INTEGER
-C             The leading dimension of the array DW.
-C             LDDW >= MAX(1,M), if JOBW <> 'N';
-C             LDDW >= 1,        if JOBW =  'N'.
-C
-C     NS      (output) INTEGER
-C             The dimension of the ALPHA-stable subsystem.
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, the leading NS elements of this array contain
-C             the Hankel singular values, ordered decreasingly, of the
-C             projection G1s of op(V)*G1*op(W) (see METHOD), where G1
-C             is the ALPHA-stable part of the original system.
-C
-C     Tolerances
-C
-C     TOL1    DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL1 contains the tolerance for
-C             determining the order of reduced system.
-C             For model reduction, the recommended value is
-C             TOL1 = c*HNORM(G1s), where c is a constant in the
-C             interval [0.00001,0.001], and HNORM(G1s) is the
-C             Hankel-norm of the projection G1s of op(V)*G1*op(W)
-C             (see METHOD), computed in HSV(1).
-C             If TOL1 <= 0 on entry, the used default value is
-C             TOL1 = NS*EPS*HNORM(G1s), where NS is the number of
-C             ALPHA-stable eigenvalues of A and EPS is the machine
-C             precision (see LAPACK Library Routine DLAMCH).
-C             If ORDSEL = 'F', the value of TOL1 is ignored.
-C             TOL1 < 1.
-C
-C     TOL2    DOUBLE PRECISION
-C             The tolerance for determining the order of a minimal
-C             realization of the ALPHA-stable part of the given system.
-C             The recommended value is TOL2 = NS*EPS*HNORM(G1s).
-C             This value is used by default if TOL2 <= 0 on entry.
-C             If TOL2 > 0 and ORDSEL = 'A', then TOL2 <= TOL1.
-C             TOL2 < 1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK = MAX(1,M,c,d),    if DICO = 'C',
-C             LIWORK = MAX(1,N,M,c,d),  if DICO = 'D', where
-C                c = 0,                          if JOBV =  'N',
-C                c = MAX(2*P,NV+P+N+6,2*NV+P+2), if JOBV <> 'N',
-C                d = 0,                          if JOBW =  'N',
-C                d = MAX(2*M,NW+M+N+6,2*NW+M+2), if JOBW <> 'N'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX( LDW1, LDW2, LDW3, LDW4 ), where
-C             for NVP = NV+P and NWM = NW+M we have
-C             LDW1 = 0 if JOBV =  'N' and
-C             LDW1 = 2*NVP*(NVP+P) + P*P +
-C                    MAX( 2*NVP*NVP + MAX( 11*NVP+16, P*NVP ),
-C                          NVP*N + MAX( NVP*N+N*N, P*N, P*M ) )
-C                      if JOBV <> 'N',
-C             LDW2 = 0 if JOBW =  'N' and
-C             LDW2 = 2*NWM*(NWM+M) + M*M +
-C                    MAX( 2*NWM*NWM + MAX( 11*NWM+16, M*NWM ),
-C                          NWM*N + MAX( NWM*N+N*N, M*N, P*M ) )
-C                      if JOBW <> 'N',
-C             LDW3 = N*(2*N + MAX(N,M,P) + 5) + N*(N+1)/2,
-C             LDW4 = N*(M+P+2) + 2*M*P + MIN(N,M) +
-C                    MAX( 3*M+1, MIN(N,M)+P ).
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NR is greater
-C                   than NSMIN, the sum of the order of the
-C                   ALPHA-unstable part and the order of a minimal
-C                   realization of the ALPHA-stable part of the given
-C                   system. In this case, the resulting NR is set equal
-C                   to NSMIN.
-C             = 2:  with ORDSEL = 'F', the selected order NR is less
-C                   than the order of the ALPHA-unstable part of the
-C                   given system. In this case NR is set equal to the
-C                   order of the ALPHA-unstable part.
-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 computation of the ordered real Schur form of A
-C                    failed;
-C             =  2:  the separation of the ALPHA-stable/unstable
-C                    diagonal blocks failed because of very close
-C                    eigenvalues;
-C             =  3:  the reduction of AV to a real Schur form failed;
-C             =  4:  the reduction of AW to a real Schur form failed;
-C             =  5:  the reduction to generalized Schur form of the
-C                    descriptor pair corresponding to the inverse of V
-C                    failed;
-C             =  6:  the reduction to generalized Schur form of the
-C                    descriptor pair corresponding to the inverse of W
-C                    failed;
-C             =  7:  the computation of Hankel singular values failed;
-C             =  8:  the computation of stable projection in the
-C                    Hankel-norm approximation algorithm failed;
-C             =  9:  the order of computed stable projection in the
-C                    Hankel-norm approximation algorithm differs
-C                    from the order of Hankel-norm approximation;
-C             = 10:  the reduction of AV-BV*inv(DV)*CV to a
-C                    real Schur form failed;
-C             = 11:  the reduction of AW-BW*inv(DW)*CW to a
-C                    real Schur form failed;
-C             = 12:  the solution of the Sylvester equation failed
-C                    because the poles of V (if JOBV = 'V') or of
-C                    conj(V) (if JOBV = 'C') are not distinct from
-C                    the poles of G1 (see METHOD);
-C             = 13:  the solution of the Sylvester equation failed
-C                    because the poles of W (if JOBW = 'W') or of
-C                    conj(W) (if JOBW = 'C') are not distinct from
-C                    the poles of G1 (see METHOD);
-C             = 14:  the solution of the Sylvester equation failed
-C                    because the zeros of V (if JOBV = 'I') or of
-C                    conj(V) (if JOBV = 'R') are not distinct from
-C                    the poles of G1sr (see METHOD);
-C             = 15:  the solution of the Sylvester equation failed
-C                    because the zeros of W (if JOBW = 'I') or of
-C                    conj(W) (if JOBW = 'R') are not distinct from
-C                    the poles of G1sr (see METHOD);
-C             = 16:  the solution of the generalized Sylvester system
-C                    failed because the zeros of V (if JOBV = 'I') or
-C                    of conj(V) (if JOBV = 'R') are not distinct from
-C                    the poles of G1sr (see METHOD);
-C             = 17:  the solution of the generalized Sylvester system
-C                    failed because the zeros of W (if JOBW = 'I') or
-C                    of conj(W) (if JOBW = 'R') are not distinct from
-C                    the poles of G1sr (see METHOD);
-C             = 18:  op(V) is not antistable;
-C             = 19:  op(W) is not antistable;
-C             = 20:  V is not invertible;
-C             = 21:  W is not invertible.
-C
-C     METHOD
-C
-C     Let G be the transfer-function matrix of the original
-C     linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t) + Du(t),                          (1)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system. The subroutine AB09JD determines
-C     the matrices of a reduced order system
-C
-C          d[z(t)] = Ar*z(t) + Br*u(t)
-C          yr(t)   = Cr*z(t) + Dr*u(t),                      (2)
-C
-C     such that the corresponding transfer-function matrix Gr minimizes
-C     the Hankel-norm of the frequency-weighted error
-C
-C             op(V)*(G-Gr)*op(W).                            (3)
-C
-C     For minimizing (3) with op(V) = V and op(W) = W, V and W are
-C     assumed to have poles distinct from those of G, while with
-C     op(V) = conj(V) and op(W) = conj(W), conj(V) and conj(W) are
-C     assumed to have poles distinct from those of G. For minimizing (3)
-C     with op(V) = inv(V) and op(W) = inv(W), V and W are assumed to
-C     have zeros distinct from the poles of G, while with
-C     op(V) = conj(inv(V)) and op(W) = conj(inv(W)), conj(V) and conj(W)
-C     are assumed to have zeros distinct from the poles of G.
-C
-C     Note: conj(G) = G'(-s) for a continuous-time system and
-C           conj(G) = G'(1/z) for a discrete-time system.
-C
-C     The following procedure is used to reduce G (see [1]):
-C
-C     1) Decompose additively G as
-C
-C          G = G1 + G2,
-C
-C        such that G1 = (A1,B1,C1,D) has only ALPHA-stable poles and
-C        G2 = (A2,B2,C2,0) has only ALPHA-unstable poles.
-C
-C     2) Compute G1s, the projection of op(V)*G1*op(W) containing the
-C        poles of G1, using explicit formulas [4] or the inverse-free
-C        descriptor system formulas of [5].
-C
-C     3) Determine G1sr, the optimal Hankel-norm approximation of G1s,
-C        of order r.
-C
-C     4) Compute G1r, the projection of inv(op(V))*G1sr*inv(op(W))
-C        containing the poles of G1sr, using explicit formulas [4]
-C        or the inverse-free descriptor system formulas of [5].
-C
-C     5) Assemble the reduced model Gr as
-C
-C           Gr = G1r + G2.
-C
-C     To reduce the weighted ALPHA-stable part G1s at step 3, the
-C     optimal Hankel-norm approximation method of [2], based on the
-C     square-root balancing projection formulas of [3], is employed.
-C
-C     The optimal weighted approximation error satisfies
-C
-C          HNORM[op(V)*(G-Gr)*op(W)] >= S(r+1),
-C
-C     where S(r+1) is the (r+1)-th Hankel singular value of G1s, the
-C     transfer-function matrix computed at step 2 of the above
-C     procedure, and HNORM(.) denotes the Hankel-norm.
-C
-C     REFERENCES
-C
-C     [1] Latham, G.A. and Anderson, B.D.O.
-C         Frequency-weighted optimal Hankel-norm approximation of stable
-C         transfer functions.
-C         Systems & Control Letters, Vol. 5, pp. 229-236, 1985.
-C
-C     [2] Glover, K.
-C         All optimal Hankel norm approximation of linear
-C         multivariable systems and their L-infinity error bounds.
-C         Int. J. Control, Vol. 36, pp. 1145-1193, 1984.
-C
-C     [3] Tombs, M.S. and Postlethwaite, I.
-C         Truncated balanced realization of stable, non-minimal
-C         state-space systems.
-C         Int. J. Control, Vol. 46, pp. 1319-1330, 1987.
-C
-C     [4] Varga, A.
-C         Explicit formulas for an efficient implementation
-C         of the frequency-weighting model reduction approach.
-C         Proc. 1993 European Control Conference, Groningen, NL,
-C         pp. 693-696, 1993.
-C
-C     [5] Varga, A.
-C         Efficient and numerically reliable implementation of the
-C         frequency-weighted Hankel-norm approximation model reduction
-C         approach.
-C         Proc. 2001 ECC, Porto, Portugal, 2001.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on an accuracy enhancing square-root
-C     technique.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, March 2001.
-C     D. Sima, University of Bucharest, April 2001.
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 2001.
-C
-C     REVISIONS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, May 2001.
-C     V. Sima, Research Institute for Informatics, Bucharest, June 2001,
-C     March 2005.
-C
-C     KEYWORDS
-C
-C     Frequency weighting, model reduction, multivariable system,
-C     state-space model, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  C100, ONE, P0001, ZERO
-      PARAMETER         ( C100 = 100.0D0, ONE = 1.0D0, P0001 = 0.0001D0,
-     $                    ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, EQUIL, JOBINV, JOBV, JOBW, ORDSEL
-      INTEGER           INFO, IWARN, LDA, LDAV, LDAW, LDB, LDBV, LDBW,
-     $                  LDC, LDCV, LDCW, LDD, LDDV, LDDW, LDWORK, M, N,
-     $                  NR, NS, NV, NW, P
-      DOUBLE PRECISION  ALPHA, TOL1, TOL2
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), AV(LDAV,*), AW(LDAW,*),
-     $                  B(LDB,*), BV(LDBV,*), BW(LDBW,*),
-     $                  C(LDC,*), CV(LDCV,*), CW(LDCW,*),
-     $                  D(LDD,*), DV(LDDV,*), DW(LDDW,*), DWORK(*),
-     $                  HSV(*)
-C     .. Local Scalars ..
-      CHARACTER         JOBVL, JOBWL
-      LOGICAL           AUTOM, CONJV, CONJW, DISCR, FIXORD, FRWGHT,
-     $                  INVFR, LEFTI, LEFTW, RIGHTI, RIGHTW
-      INTEGER           IERR, IWARNL, KAV, KAW, KBV, KBW, KCV, KCW, KDV,
-     $                  KDW, KEV, KEW, KI, KL, KU, KW, LDABV, LDABW,
-     $                  LDCDV, LDCDW, LW, NRA, NU, NU1, NVP, NWM, RANK
-      DOUBLE PRECISION  ALPWRK, MAXRED, RCOND, SQREPS, TOL, WRKOPT
-C     .. Local Arrays ..
-      DOUBLE PRECISION  TEMP(1)
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH
-      EXTERNAL          DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB07ND, AB08MD, AB09CX, AB09JV, AB09JW, AG07BD,
-     $                  DLACPY, TB01ID, TB01KD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      DISCR  = LSAME( DICO,   'D' )
-      FIXORD = LSAME( ORDSEL, 'F' )
-      LEFTI  = LSAME( JOBV, 'I' ) .OR. LSAME( JOBV, 'R' )
-      LEFTW  = LSAME( JOBV, 'V' ) .OR. LSAME( JOBV, 'C' ) .OR. LEFTI
-      CONJV  = LSAME( JOBV, 'C' ) .OR. LSAME( JOBV, 'R' )
-      RIGHTI = LSAME( JOBW, 'I' ) .OR. LSAME( JOBW, 'R' )
-      RIGHTW = LSAME( JOBW, 'W' ) .OR. LSAME( JOBW, 'C' ) .OR. RIGHTI
-      CONJW  = LSAME( JOBW, 'C' ) .OR. LSAME( JOBW, 'R' )
-      FRWGHT = LEFTW .OR. RIGHTW
-      INVFR  = LSAME( JOBINV, 'N' )
-      AUTOM  = LSAME( JOBINV, 'A' )
-C
-      LW = 1
-      IF( LEFTW ) THEN
-         NVP = NV + P
-         LW  = MAX( LW, 2*NVP*( NVP + P ) + P*P +
-     $              MAX( 2*NVP*NVP + MAX( 11*NVP + 16, P*NVP ),
-     $                   NVP*N + MAX( NVP*N+N*N, P*N, P*M ) ) )
-      END IF
-      IF( RIGHTW ) THEN
-         NWM = NW + M
-         LW  = MAX( LW, 2*NWM*( NWM + M ) + M*M +
-     $              MAX( 2*NWM*NWM + MAX( 11*NWM + 16, M*NWM ),
-     $                   NWM*N + MAX( NWM*N+N*N, M*N, P*M ) ) )
-      END IF
-      LW = MAX( LW, N*( 2*N + MAX( N, M, P ) + 5 ) + ( N*( N + 1 ) )/2 )
-      LW = MAX( LW, N*( M + P + 2 ) + 2*M*P + MIN( N, M ) +
-     $                             MAX ( 3*M + 1, MIN( N, M ) + P ) )
-C
-C     Check the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( JOBV, 'N' ) .OR. LEFTW ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( LSAME( JOBW, 'N' ) .OR. RIGHTW ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( INVFR .OR. AUTOM .OR. LSAME( JOBINV, 'I' ) ) )
-     $   THEN
-         INFO = -3
-      ELSE IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -4
-      ELSE IF( .NOT. ( LSAME( EQUIL, 'S' ) .OR.
-     $                 LSAME( EQUIL, 'N' ) ) ) THEN
-         INFO = -5
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -6
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( NV.LT.0 ) THEN
-         INFO = -8
-      ELSE IF( NW.LT.0 ) THEN
-         INFO = -9
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -10
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -11
-      ELSE IF( FIXORD .AND. ( NR.LT.0 .OR. NR.GT.N ) ) THEN
-         INFO = -12
-      ELSE IF( ( DISCR .AND. ( ALPHA.LT.ZERO .OR. ALPHA.GT.ONE ) ) .OR.
-     $    ( .NOT.DISCR .AND.   ALPHA.GT.ZERO ) ) THEN
-         INFO = -13
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -15
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -17
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -19
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -21
-      ELSE IF( LDAV.LT.1 .OR. ( LEFTW  .AND. LDAV.LT.NV ) ) THEN
-         INFO = -23
-      ELSE IF( LDBV.LT.1 .OR. ( LEFTW  .AND. LDBV.LT.NV ) ) THEN
-         INFO = -25
-      ELSE IF( LDCV.LT.1 .OR. ( LEFTW  .AND. LDCV.LT.P  ) ) THEN
-         INFO = -27
-      ELSE IF( LDDV.LT.1 .OR. ( LEFTW  .AND. LDDV.LT.P  ) ) THEN
-         INFO = -29
-      ELSE IF( LDAW.LT.1 .OR. ( RIGHTW .AND. LDAW.LT.NW ) ) THEN
-         INFO = -31
-      ELSE IF( LDBW.LT.1 .OR. ( RIGHTW .AND. LDBW.LT.NW ) ) THEN
-         INFO = -33
-      ELSE IF( LDCW.LT.1 .OR. ( RIGHTW .AND. LDCW.LT.M  ) ) THEN
-         INFO = -35
-      ELSE IF( LDDW.LT.1 .OR. ( RIGHTW .AND. LDDW.LT.M  ) ) THEN
-         INFO = -37
-      ELSE IF( TOL1.GE.ONE ) THEN
-         INFO = -40
-      ELSE IF( ( TOL2.GT.ZERO .AND. .NOT.FIXORD .AND. TOL2.GT.TOL1 )
-     $      .OR. TOL2.GE.ONE ) THEN
-         INFO = -41
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -44
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09JD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 ) THEN
-         NR = 0
-         NS = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      IF( LSAME( EQUIL, 'S' ) ) THEN
-C
-C        Scale simultaneously the matrices A, B and C:
-C        A <- inv(D)*A*D,  B <- inv(D)*B  and  C <- C*D,  where D is a
-C        diagonal matrix.
-C        Workspace: N.
-C
-         MAXRED = C100
-         CALL TB01ID( 'All', N, M, P, MAXRED, A, LDA, B, LDB, C, LDC,
-     $                DWORK, INFO )
-      END IF
-C
-C     Correct the value of ALPHA to ensure stability.
-C
-      ALPWRK = ALPHA
-      SQREPS = SQRT( DLAMCH( 'E' ) )
-      IF( DISCR ) THEN
-         IF( ALPHA.EQ.ONE ) ALPWRK = ONE - SQREPS
-      ELSE
-         IF( ALPHA.EQ.ZERO ) ALPWRK = -SQREPS
-      END IF
-C
-C     Allocate working storage.
-C
-      KU = 1
-      KL = KU + N*N
-      KI = KL + N
-      KW = KI + N
-C
-C     Compute an additive decomposition G = G1 + G2, where G1
-C     is the ALPHA-stable projection of G.
-C
-C     Reduce A to a block-diagonal real Schur form, with the NU-th order
-C     ALPHA-unstable part in the leading diagonal position, using a
-C     non-orthogonal similarity transformation A <- inv(T)*A*T and
-C     apply the transformation to B and C: B <- inv(T)*B and C <- C*T.
-C
-C     Workspace needed:      N*(N+2);
-C     Additional workspace:  need   3*N;
-C                            prefer larger.
-C
-      CALL TB01KD( DICO, 'Unstable', 'General', N, M, P, ALPWRK, A, LDA,
-     $             B, LDB, C, LDC, NU, DWORK(KU), N, DWORK(KL),
-     $             DWORK(KI), DWORK(KW), LDWORK-KW+1, IERR )
-C
-      IF( IERR.NE.0 ) THEN
-         IF( IERR.NE.3 ) THEN
-            INFO = 1
-         ELSE
-            INFO = 2
-         END IF
-         RETURN
-      END IF
-C
-      WRKOPT = DWORK(KW) + DBLE( KW-1 )
-      IWARNL = 0
-C
-      NS = N - NU
-      IF( FIXORD ) THEN
-         NRA = MAX( 0, NR-NU )
-         IF( NR.LT.NU )
-     $      IWARNL = 2
-      ELSE
-         NRA = 0
-      END IF
-C
-C     Finish if only unstable part is present.
-C
-      IF( NS.EQ.0 ) THEN
-         NR = NU
-         DWORK(1) = WRKOPT
-         RETURN
-      END IF
-C
-      NU1 = NU + 1
-      IF( CONJV ) THEN
-         JOBVL = 'C'
-      ELSE
-         JOBVL = 'V'
-      END IF
-      IF( CONJW ) THEN
-         JOBWL = 'C'
-      ELSE
-         JOBWL = 'W'
-      END IF
-      IF( LEFTW ) THEN
-C
-C        Check if V is invertible.
-C        Real workspace:    need   (NV+P)**2 + MAX( P + MAX(3*P,NV),
-C                                  MIN(P+1,NV) + MAX(3*(P+1),NV+P) );
-C                           prefer larger.
-C        Integer workspace: need   2*NV+P+2.
-C
-         TOL = ZERO
-         CALL AB08MD( 'S', NV, P, P, AV, LDAV, BV, LDBV, CV, LDCV,
-     $                DV, LDDV, RANK, TOL, IWORK, DWORK, LDWORK,
-     $                IERR )
-         IF( RANK.NE.P ) THEN
-            INFO = 20
-            RETURN
-         END IF
-         WRKOPT = MAX( WRKOPT, DWORK(1) )
-C
-         IF( LEFTI ) THEN
-            IF( INVFR ) THEN
-               IERR = 1
-            ELSE
-C
-C              Allocate storage for a standard inverse of V.
-C              Workspace: need  NV*(NV+2*P) + P*P.
-C
-               KAV = 1
-               KBV = KAV + NV*NV
-               KCV = KBV + NV*P
-               KDV = KCV + P*NV
-               KW  = KDV + P*P
-C
-               LDABV = MAX( NV, 1 )
-               LDCDV = P
-               CALL DLACPY( 'Full', NV, NV, AV, LDAV,
-     $                      DWORK(KAV), LDABV )
-               CALL DLACPY( 'Full', NV, P,  BV, LDBV,
-     $                      DWORK(KBV), LDABV )
-               CALL DLACPY( 'Full', P,  NV, CV, LDCV,
-     $                      DWORK(KCV), LDCDV )
-               CALL DLACPY( 'Full', P,  P,  DV, LDDV,
-     $                      DWORK(KDV), LDCDV )
-C
-C              Compute the standard inverse of V.
-C              Additional real workspace:   need   MAX(1,4*P);
-C                                           prefer larger.
-C              Integer workspace:           need   2*P.
-C
-               CALL AB07ND( NV, P, DWORK(KAV), LDABV, DWORK(KBV), LDABV,
-     $                      DWORK(KCV), LDCDV, DWORK(KDV), LDCDV,
-     $                      RCOND, IWORK, DWORK(KW), LDWORK-KW+1, IERR )
-               WRKOPT = MAX( WRKOPT, DWORK(KW) + DBLE( KW-1 ) )
-C
-C              Check if inversion is accurate.
-C
-               IF( AUTOM ) THEN
-                  IF( IERR.EQ.0 .AND. RCOND.LE.P0001  ) IERR = 1
-               ELSE
-                  IF( IERR.EQ.0 .AND. RCOND.LE.SQREPS ) IERR = 1
-               END IF
-               IF( IERR.NE.0 .AND. NV.EQ.0 ) THEN
-                  INFO = 20
-                  RETURN
-               END IF
-            END IF
-C
-            IF( IERR.NE.0 ) THEN
-C
-C              Allocate storage for a descriptor inverse of V.
-C
-               KAV = 1
-               KEV = KAV + NVP*NVP
-               KBV = KEV + NVP*NVP
-               KCV = KBV + NVP*P
-               KDV = KCV + P*NVP
-               KW  = KDV + P*P
-C
-               LDABV = MAX( NVP, 1 )
-               LDCDV = P
-C
-C              DV is singular or ill-conditioned.
-C              Form a descriptor inverse of V.
-C              Workspace: need  2*(NV+P)*(NV+2*P) + P*P.
-C
-               CALL AG07BD( 'I', NV, P, AV, LDAV, TEMP, 1, BV, LDBV,
-     $                      CV, LDCV, DV, LDDV, DWORK(KAV), LDABV,
-     $                      DWORK(KEV), LDABV, DWORK(KBV), LDABV,
-     $                      DWORK(KCV), LDCDV, DWORK(KDV), LDCDV, IERR )
-C
-C              Compute the projection containing the poles of weighted
-C              reduced ALPHA-stable part using descriptor inverse of V
-C              of order NVP = NV + P.
-C              Additional real workspace: need
-C                 MAX( 2*NVP*NVP + MAX( 11*NVP+16, P*NVP ),
-C                      NVP*N + MAX( NVP*N+N*N, P*N, P*M ) );
-C                 prefer larger.
-C              Integer workspace: need NVP+N+6.
-C
-               CALL AB09JV( JOBVL, DICO, 'G', 'C', NS, M, P, NVP, P,
-     $                      A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $                      C(1,NU1), LDC, D, LDD,
-     $                      DWORK(KAV), LDABV, DWORK(KEV), LDABV,
-     $                      DWORK(KBV), LDABV, DWORK(KCV), LDCDV,
-     $                      DWORK(KDV), LDCDV, IWORK, DWORK(KW),
-     $                      LDWORK-KW+1, IERR )
-               IF( IERR.NE.0 ) THEN
-                  IF( IERR.EQ.1 ) THEN
-                     INFO = 5
-                  ELSE IF( IERR.EQ.2 ) THEN
-                     INFO = 16
-                  ELSE IF( IERR.EQ.4 ) THEN
-                     INFO = 18
-                  END IF
-                  RETURN
-               END IF
-            ELSE
-C
-C              Compute the projection containing the poles of weighted
-C              reduced ALPHA-stable part using explicit inverse of V.
-C              Additional real workspace: need
-C                 MAX( NV*(NV+5), NV*N + MAX( a, P*N, P*M ) )
-C                      a = 0,    if DICO = 'C' or  JOBVL = 'V',
-C                      a = 2*NV, if DICO = 'D' and JOBVL = 'C';
-C                 prefer larger.
-C
-               CALL AB09JV( JOBVL, DICO, 'I', 'C', NS, M, P, NV, P,
-     $                      A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $                      C(1,NU1), LDC, D, LDD, DWORK(KAV), LDABV,
-     $                      TEMP, 1, DWORK(KBV), LDABV,
-     $                      DWORK(KCV), LDCDV, DWORK(KDV), LDCDV, IWORK,
-     $                      DWORK(KW), LDWORK-KW+1, IERR )
-               IF( IERR.NE.0 ) THEN
-                  IF( IERR.EQ.1 ) THEN
-                     INFO = 10
-                  ELSE IF( IERR.EQ.3 ) THEN
-                     INFO = 14
-                  ELSE IF( IERR.EQ.4 ) THEN
-                     INFO = 18
-                  END IF
-                  RETURN
-               END IF
-            END IF
-C
-            WRKOPT = MAX( WRKOPT, DWORK(KW) + DBLE( KW - 1 ) )
-         ELSE
-C
-C           Compute the projection of V*G1 or conj(V)*G1 containing the
-C           poles of G.
-C
-C           Workspace need:
-C           real   MAX( 1, NV*(NV+5), NV*N + MAX( a, P*N, P*M ) )
-C                       a = 0,    if DICO = 'C' or  JOBVL = 'V',
-C                       a = 2*NV, if DICO = 'D' and JOBVL = 'C';
-C           prefer larger.
-C
-            CALL AB09JV( JOBVL, DICO, 'I', 'C', NS, M, P, NV, P,
-     $                   A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $                   C(1,NU1), LDC, D, LDD, AV, LDAV,
-     $                   TEMP, 1, BV, LDBV, CV, LDCV, DV, LDDV, IWORK,
-     $                   DWORK, LDWORK, IERR )
-            IF( IERR.NE.0 ) THEN
-               IF( IERR.EQ.1 ) THEN
-                  INFO = 3
-               ELSE IF( IERR.EQ.3 ) THEN
-                  INFO = 12
-               ELSE IF( IERR.EQ.4 ) THEN
-                  INFO = 18
-               END IF
-               RETURN
-            END IF
-C
-            WRKOPT = MAX( WRKOPT, DWORK(1) )
-         END IF
-      END IF
-C
-      IF( RIGHTW ) THEN
-C
-C        Check if W is invertible.
-C        Real workspace:    need   (NW+M)**2 + MAX( M + MAX(3*M,NW),
-C                                  MIN(M+1,NW) + MAX(3*(M+1),NW+M) );
-C                           prefer larger.
-C        Integer workspace: need   2*NW+M+2.
-C
-         TOL = ZERO
-         CALL AB08MD( 'S', NW, M, M, AW, LDAW, BW, LDBW, CW, LDCW,
-     $                DW, LDDW, RANK, TOL, IWORK, DWORK, LDWORK,
-     $                IERR )
-         IF( RANK.NE.M ) THEN
-            INFO = 21
-            RETURN
-         END IF
-         WRKOPT = MAX( WRKOPT, DWORK(1) )
-C
-         IF( RIGHTI ) THEN
-            IF( INVFR ) THEN
-               IERR = 1
-            ELSE
-C
-C              Allocate storage for a standard inverse of W.
-C              Workspace: need  NW*(NW+2*M) + M*M.
-C
-               KAW = 1
-               KBW = KAW + NW*NW
-               KCW = KBW + NW*M
-               KDW = KCW + M*NW
-               KW  = KDW + M*M
-C
-               LDABW = MAX( NW, 1 )
-               LDCDW = M
-               CALL DLACPY( 'Full', NW, NW, AW, LDAW,
-     $                      DWORK(KAW), LDABW )
-               CALL DLACPY( 'Full', NW, M,  BW, LDBW,
-     $                      DWORK(KBW), LDABW )
-               CALL DLACPY( 'Full', M,  NW, CW, LDCW,
-     $                      DWORK(KCW), LDCDW )
-               CALL DLACPY( 'Full', M,  M,  DW, LDDW,
-     $                      DWORK(KDW), LDCDW )
-C
-C              Compute the standard inverse of W.
-C              Additional real workspace:   need   MAX(1,4*M);
-C                                           prefer larger.
-C              Integer workspace:           need   2*M.
-C
-               CALL AB07ND( NW, M, DWORK(KAW), LDABW, DWORK(KBW), LDABW,
-     $                      DWORK(KCW), LDCDW, DWORK(KDW), LDCDW,
-     $                      RCOND, IWORK, DWORK(KW), LDWORK-KW+1, IERR )
-               WRKOPT = MAX( WRKOPT, DWORK(KW) + DBLE( KW-1 ) )
-C
-C              Check if inversion is accurate.
-C
-               IF( AUTOM ) THEN
-                  IF( IERR.EQ.0 .AND. RCOND.LE.P0001  ) IERR = 1
-               ELSE
-                  IF( IERR.EQ.0 .AND. RCOND.LE.SQREPS ) IERR = 1
-               END IF
-               IF( IERR.NE.0 .AND. NW.EQ.0 ) THEN
-                  INFO = 21
-                  RETURN
-               END IF
-            END IF
-C
-            IF( IERR.NE.0 ) THEN
-C
-C              Allocate storage for a descriptor inverse of W.
-C
-               KAW = 1
-               KEW = KAW + NWM*NWM
-               KBW = KEW + NWM*NWM
-               KCW = KBW + NWM*M
-               KDW = KCW + M*NWM
-               KW  = KDW + M*M
-C
-               LDABW = MAX( NWM, 1 )
-               LDCDW = M
-C
-C              DW is singular or ill-conditioned.
-C              Form the descriptor inverse of W.
-C              Workspace: need  2*(NW+M)*(NW+2*M) + M*M.
-C
-               CALL AG07BD( 'I', NW, M, AW, LDAW, TEMP, 1, BW, LDBW,
-     $                      CW, LDCW, DW, LDDW, DWORK(KAW), LDABW,
-     $                      DWORK(KEW), LDABW, DWORK(KBW), LDABW,
-     $                      DWORK(KCW), LDCDW, DWORK(KDW), LDCDW, IERR )
-C
-C              Compute the projection containing the poles of weighted
-C              reduced ALPHA-stable part using descriptor inverse of W
-C              of order NWM = NW + M.
-C              Additional real workspace: need
-C                 MAX( 2*NWM*NWM + MAX( 11*NWM+16, M*NWM ),
-C                      NWM*N + MAX( NWM*N+N*N, M*N, P*M ) );
-C                 prefer larger.
-C              Integer workspace: need NWM+N+6.
-C
-               CALL AB09JW( JOBWL, DICO, 'G', 'C', NS, M, P, NWM, M,
-     $                      A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $                      C(1,NU1), LDC, D, LDD, DWORK(KAW), LDABW,
-     $                      DWORK(KEW), LDABW, DWORK(KBW), LDABW,
-     $                      DWORK(KCW), LDCDW, DWORK(KDW), LDCDW,
-     $                      IWORK, DWORK(KW), LDWORK-KW+1, IERR )
-               IF( IERR.NE.0 ) THEN
-                  IF( IERR.EQ.1 ) THEN
-                     INFO = 6
-                  ELSE IF( IERR.EQ.2 ) THEN
-                     INFO = 17
-                  ELSE IF( IERR.EQ.4 ) THEN
-                     INFO = 19
-                  END IF
-                  RETURN
-               END IF
-            ELSE
-C
-C              Compute the projection containing the poles of weighted
-C              reduced ALPHA-stable part using explicit inverse of W.
-C              Additional real workspace: need
-C                 MAX( NW*(NW+5), NW*N + MAX( a, M*N, P*M ) )
-C                      a = 0,    if DICO = 'C' or  JOBWL = 'W',
-C                      a = 2*NW, if DICO = 'D' and JOBWL = 'C';
-C                 prefer larger.
-C
-               CALL AB09JW( JOBWL, DICO, 'I', 'C', NS, M, P, NW, M,
-     $                      A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $                      C(1,NU1), LDC, D, LDD, DWORK(KAW), LDABW,
-     $                      TEMP, 1, DWORK(KBW), LDABW,
-     $                      DWORK(KCW), LDCDW, DWORK(KDW), LDCDW,
-     $                      IWORK, DWORK(KW), LDWORK-KW+1, IERR )
-               IF( IERR.NE.0 ) THEN
-                  IF( IERR.EQ.1 ) THEN
-                     INFO = 11
-                  ELSE IF( IERR.EQ.3 ) THEN
-                     INFO = 15
-                  ELSE IF( IERR.EQ.4 ) THEN
-                     INFO = 19
-                  END IF
-                  RETURN
-               END IF
-            END IF
-C
-            WRKOPT = MAX( WRKOPT, DWORK(KW) + DBLE( KW - 1 ) )
-         ELSE
-C
-C           Compute the projection G1s of V*G1*W or conj(V)*G1*conj(W)
-C           containing the poles of G.
-C
-C           Workspace need:
-C           real   MAX( 1, NW*(NW+5), NW*N + MAX( b, M*N, P*M ) )
-C                    b = 0,    if DICO = 'C' or  JOBWL = 'W',
-C                    b = 2*NW, if DICO = 'D' and JOBWL = 'C';
-C           prefer larger.
-C
-            CALL AB09JW( JOBWL, DICO, 'I', 'C', NS, M, P, NW, M,
-     $                   A(NU1,NU1), LDA, B(NU1,1), LDB, C(1,NU1), LDC,
-     $                   D, LDD, AW, LDAW, TEMP, 1, BW, LDBW, CW, LDCW,
-     $                   DW, LDDW, IWORK, DWORK, LDWORK, IERR )
-            IF( IERR.NE.0 ) THEN
-               IF( IERR.EQ.1 ) THEN
-                  INFO = 4
-               ELSE IF( IERR.EQ.3 ) THEN
-                  INFO = 13
-               ELSE IF( IERR.EQ.4 ) THEN
-                  INFO = 19
-               END IF
-               RETURN
-            END IF
-C
-            WRKOPT = MAX( WRKOPT, DWORK(1) )
-         END IF
-      END IF
-C
-C     Determine a reduced order approximation G1sr of G1s using the
-C     Hankel-norm approximation method. The resulting A(NU1:N,NU1:N)
-C     is further in a real Schur form.
-C
-C     Workspace: need   MAX( LDW3, LDW4 ),
-C                LDW3 = N*(2*N + MAX(N,M,P) + 5) + N*(N+1)/2,
-C                LDW4 = N*(M+P+2) + 2*M*P + MIN(N,M) +
-C                       MAX( 3*M+1, MIN(N,M)+P );
-C                prefer larger.
-C
-      CALL AB09CX( DICO, ORDSEL, NS, M, P, NRA, A(NU1,NU1), LDA,
-     $             B(NU1,1), LDB, C(1,NU1), LDC, D, LDD, HSV, TOL1,
-     $             TOL2, IWORK, DWORK, LDWORK, IWARN, IERR )
-C
-      IF( IERR.NE.0 ) THEN
-C
-C        Set INFO = 7, 8 or 9.
-C
-         INFO = IERR + 5
-         RETURN
-      END IF
-C
-      IWARN  = MAX( IWARNL, IWARN )
-      WRKOPT = MAX( WRKOPT, DWORK(1) )
-C
-      IF( LEFTW ) THEN
-         IF( .NOT.LEFTI ) THEN
-            IF( INVFR ) THEN
-               IERR = 1
-            ELSE
-C
-C              Allocate storage for a standard inverse of V.
-C              Workspace: need  NV*(NV+2*P) + P*P.
-C
-               KAV = 1
-               KBV = KAV + NV*NV
-               KCV = KBV + NV*P
-               KDV = KCV + P*NV
-               KW  = KDV + P*P
-C
-               LDABV = MAX( NV, 1 )
-               LDCDV = P
-               CALL DLACPY( 'Full', NV, NV, AV, LDAV,
-     $                      DWORK(KAV), LDABV )
-               CALL DLACPY( 'Full', NV, P,  BV, LDBV,
-     $                      DWORK(KBV), LDABV )
-               CALL DLACPY( 'Full', P,  NV, CV, LDCV,
-     $                      DWORK(KCV), LDCDV )
-               CALL DLACPY( 'Full', P,  P,  DV, LDDV,
-     $                      DWORK(KDV), LDCDV )
-C
-C              Compute the standard inverse of V.
-C              Additional real workspace:   need   MAX(1,4*P);
-C                                           prefer larger.
-C              Integer workspace:           need   2*P.
-C
-               CALL AB07ND( NV, P, DWORK(KAV), LDABV, DWORK(KBV), LDABV,
-     $                      DWORK(KCV), LDCDV, DWORK(KDV), LDCDV,
-     $                      RCOND, IWORK, DWORK(KW), LDWORK-KW+1, IERR )
-               WRKOPT = MAX( WRKOPT, DWORK(KW) + DBLE( KW-1 ) )
-C
-C              Check if inversion is accurate.
-C
-               IF( AUTOM ) THEN
-                  IF( IERR.EQ.0 .AND. RCOND.LE.P0001  ) IERR = 1
-               ELSE
-                  IF( IERR.EQ.0 .AND. RCOND.LE.SQREPS ) IERR = 1
-               END IF
-               IF( IERR.NE.0 .AND. NV.EQ.0 ) THEN
-                  INFO = 20
-                  RETURN
-               END IF
-            END IF
-C
-            IF( IERR.NE.0 ) THEN
-C
-C              Allocate storage for a descriptor inverse of V.
-C
-               KAV = 1
-               KEV = KAV + NVP*NVP
-               KBV = KEV + NVP*NVP
-               KCV = KBV + NVP*P
-               KDV = KCV + P*NVP
-               KW  = KDV + P*P
-C
-               LDABV = MAX( NVP, 1 )
-               LDCDV = P
-C
-C              DV is singular or ill-conditioned.
-C              Form a descriptor inverse of V.
-C              Workspace: need  2*(NV+P)*(NV+2*P) + P*P.
-C
-               CALL AG07BD( 'I', NV, P, AV, LDAV, TEMP, 1, BV, LDBV,
-     $                      CV, LDCV, DV, LDDV, DWORK(KAV), LDABV,
-     $                      DWORK(KEV), LDABV, DWORK(KBV), LDABV,
-     $                      DWORK(KCV), LDCDV, DWORK(KDV), LDCDV, IERR )
-C
-C              Compute the projection containing the poles of weighted
-C              reduced ALPHA-stable part using descriptor inverse of V
-C              of order NVP = NV + P.
-C              Additional real workspace: need
-C                 MAX( 2*NVP*NVP + MAX( 11*NVP+16, P*NVP ),
-C                      NVP*N + MAX( NVP*N+N*N, P*N, P*M ) );
-C                 prefer larger.
-C              Integer workspace: need NVP+N+6.
-C
-               CALL AB09JV( JOBVL, DICO, 'G', 'N', NRA, M, P, NVP, P,
-     $                      A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $                      C(1,NU1), LDC, D, LDD,
-     $                      DWORK(KAV), LDABV, DWORK(KEV), LDABV,
-     $                      DWORK(KBV), LDABV, DWORK(KCV), LDCDV,
-     $                      DWORK(KDV), LDCDV, IWORK, DWORK(KW),
-     $                      LDWORK-KW+1, IERR )
-               IF( IERR.NE.0 ) THEN
-                  IF( IERR.EQ.1 ) THEN
-                     INFO = 5
-                  ELSE IF( IERR.EQ.2 ) THEN
-                     INFO = 16
-                  END IF
-                  RETURN
-               END IF
-            ELSE
-C
-C              Compute the projection containing the poles of weighted
-C              reduced ALPHA-stable part using explicit inverse of V.
-C              Additional real workspace: need
-C                 MAX( NV*(NV+5), NV*N + MAX( a, P*N, P*M ) )
-C                      a = 0,    if DICO = 'C' or  JOBVL = 'V',
-C                      a = 2*NV, if DICO = 'D' and JOBVL = 'C';
-C                 prefer larger.
-C
-               CALL AB09JV( JOBVL, DICO, 'I', 'N', NRA, M, P, NV, P,
-     $                      A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $                      C(1,NU1), LDC, D, LDD, DWORK(KAV), LDABV,
-     $                      TEMP, 1, DWORK(KBV), LDABV,
-     $                      DWORK(KCV), LDCDV, DWORK(KDV), LDCDV, IWORK,
-     $                      DWORK(KW), LDWORK-KW+1, IERR )
-               IF( IERR.NE.0 ) THEN
-                  IF( IERR.EQ.1 ) THEN
-                     INFO = 10
-                  ELSE IF( IERR.EQ.3 ) THEN
-                     INFO = 14
-                  END IF
-                  RETURN
-               END IF
-            END IF
-C
-            WRKOPT = MAX( WRKOPT, DWORK(KW) + DBLE( KW - 1 ) )
-         ELSE
-C
-C           Compute the projection of V*G1sr or conj(V)*G1sr containing
-C           the poles of G.
-C
-C           Workspace need:
-C           real    MAX( 1, NV*(NV+5), NV*N + MAX( a, P*N, P*M ) )
-C                        a = 0,    if DICO = 'C' or  JOBVL = 'V',
-C                        a = 2*NV, if DICO = 'D' and JOBVL = 'C';
-C           prefer larger.
-C
-            CALL AB09JV( JOBVL, DICO, 'I', 'N', NRA, M, P, NV, P,
-     $                   A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $                   C(1,NU1), LDC, D, LDD, AV, LDAV,
-     $                   TEMP, 1, BV, LDBV, CV, LDCV, DV, LDDV, IWORK,
-     $                   DWORK, LDWORK, IERR )
-            IF( IERR.NE.0 ) THEN
-               IF( IERR.EQ.1 ) THEN
-                  INFO = 3
-               ELSE IF( IERR.EQ.3 ) THEN
-                  INFO = 12
-               END IF
-               RETURN
-            END IF
-C
-            WRKOPT = MAX( WRKOPT, DWORK(1) )
-         END IF
-      END IF
-C
-      IF( RIGHTW ) THEN
-         IF( .NOT.RIGHTI ) THEN
-            IF( INVFR ) THEN
-               IERR = 1
-            ELSE
-C
-C              Allocate storage for a standard inverse of W.
-C              Workspace: need  NW*(NW+2*M) + M*M.
-C
-               KAW = 1
-               KBW = KAW + NW*NW
-               KCW = KBW + NW*M
-               KDW = KCW + M*NW
-               KW  = KDW + M*M
-C
-               LDABW = MAX( NW, 1 )
-               LDCDW = M
-               CALL DLACPY( 'Full', NW, NW, AW, LDAW,
-     $                      DWORK(KAW), LDABW )
-               CALL DLACPY( 'Full', NW, M,  BW, LDBW,
-     $                      DWORK(KBW), LDABW )
-               CALL DLACPY( 'Full', M,  NW, CW, LDCW,
-     $                      DWORK(KCW), LDCDW )
-               CALL DLACPY( 'Full', M,  M,  DW, LDDW,
-     $                      DWORK(KDW), LDCDW )
-C
-C              Compute the standard inverse of W.
-C              Additional real workspace:   need   MAX(1,4*M);
-C                                           prefer larger.
-C              Integer workspace:           need   2*M.
-C
-               CALL AB07ND( NW, M, DWORK(KAW), LDABW, DWORK(KBW), LDABW,
-     $                      DWORK(KCW), LDCDW, DWORK(KDW), LDCDW,
-     $                      RCOND, IWORK, DWORK(KW), LDWORK-KW+1, IERR )
-               WRKOPT = MAX( WRKOPT, DWORK(KW) + DBLE( KW-1 ) )
-C
-C              Check if inversion is accurate.
-C
-               IF( AUTOM ) THEN
-                  IF( IERR.EQ.0 .AND. RCOND.LE.P0001  ) IERR = 1
-               ELSE
-                  IF( IERR.EQ.0 .AND. RCOND.LE.SQREPS ) IERR = 1
-               END IF
-               IF( IERR.NE.0 .AND. NW.EQ.0 ) THEN
-                  INFO = 21
-                  RETURN
-               END IF
-            END IF
-C
-            IF( IERR.NE.0 ) THEN
-C
-C              Allocate storage for a descriptor inverse of W.
-C
-               KAW = 1
-               KEW = KAW + NWM*NWM
-               KBW = KEW + NWM*NWM
-               KCW = KBW + NWM*M
-               KDW = KCW + M*NWM
-               KW  = KDW + M*M
-C
-               LDABW = MAX( NWM, 1 )
-               LDCDW = M
-C
-C              DW is singular or ill-conditioned.
-C              Form the descriptor inverse of W.
-C              Workspace: need  2*(NW+M)*(NW+2*M) + M*M.
-C
-               CALL AG07BD( 'I', NW, M, AW, LDAW, TEMP, 1, BW, LDBW,
-     $                      CW, LDCW, DW, LDDW, DWORK(KAW), LDABW,
-     $                      DWORK(KEW), LDABW, DWORK(KBW), LDABW,
-     $                      DWORK(KCW), LDCDW, DWORK(KDW), LDCDW, IERR )
-C
-C              Compute the projection containing the poles of weighted
-C              reduced ALPHA-stable part using descriptor inverse of W
-C              of order NWM = NW + M.
-C              Additional real workspace: need
-C                 MAX( 2*NWM*NWM + MAX( 11*NWM+16, M*NWM ),
-C                      NWM*N + MAX( NWM*N+N*N, M*N, P*M ) );
-C                 prefer larger.
-C              Integer workspace: need NWM+N+6.
-C
-               CALL AB09JW( JOBWL, DICO, 'G', 'N', NRA, M, P, NWM, M,
-     $                      A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $                      C(1,NU1), LDC, D, LDD, DWORK(KAW), LDABW,
-     $                      DWORK(KEW), LDABW, DWORK(KBW), LDABW,
-     $                      DWORK(KCW), LDCDW, DWORK(KDW), LDCDW,
-     $                      IWORK, DWORK(KW), LDWORK-KW+1, IERR )
-               IF( IERR.NE.0 ) THEN
-                  IF( IERR.EQ.1 ) THEN
-                     INFO = 6
-                  ELSE IF( IERR.EQ.2 ) THEN
-                     INFO = 17
-                  END IF
-                  RETURN
-               END IF
-            ELSE
-C
-C              Compute the projection containing the poles of weighted
-C              reduced ALPHA-stable part using explicit inverse of W.
-C              Additional real workspace: need
-C                 MAX( NW*(NW+5), NW*N + MAX( a, M*N, P*M ) )
-C                      a = 0,    if DICO = 'C' or  JOBWL = 'W',
-C                      a = 2*NW, if DICO = 'D' and JOBWL = 'C';
-C                 prefer larger.
-C
-               CALL AB09JW( JOBWL, DICO, 'I', 'N', NRA, M, P, NW, M,
-     $                      A(NU1,NU1), LDA, B(NU1,1), LDB,
-     $                      C(1,NU1), LDC, D, LDD, DWORK(KAW), LDABW,
-     $                      TEMP, 1, DWORK(KBW), LDABW,
-     $                      DWORK(KCW), LDCDW, DWORK(KDW), LDCDW,
-     $                      IWORK, DWORK(KW), LDWORK-KW+1, IERR )
-               IF( IERR.NE.0 ) THEN
-                  IF( IERR.EQ.1 ) THEN
-                     INFO = 11
-                  ELSE IF( IERR.EQ.3 ) THEN
-                     INFO = 15
-                  END IF
-                  RETURN
-               END IF
-            END IF
-C
-            WRKOPT = MAX( WRKOPT, DWORK(KW) + DBLE( KW - 1 ) )
-         ELSE
-C
-C           Compute the projection G1r of V*G1sr*W or
-C           conj(V)*G1sr*conj(W) containing the poles of G.
-C
-C           Workspace need:
-C           real   MAX( 1, NW*(NW+5), NW*N + MAX( b, M*N, P*M ) )
-C                    b = 0,    if DICO = 'C' or  JOBWL = 'W',
-C                    b = 2*NW, if DICO = 'D' and JOBWL = 'C';
-C           prefer larger.
-C
-            CALL AB09JW( JOBWL, DICO, 'I', 'N', NRA, M, P, NW, M,
-     $                   A(NU1,NU1), LDA, B(NU1,1), LDB, C(1,NU1), LDC,
-     $                   D, LDD, AW, LDAW, TEMP, 1, BW, LDBW, CW, LDCW,
-     $                   DW, LDDW, IWORK, DWORK, LDWORK, IERR )
-C
-            IF( IERR.NE.0 ) THEN
-               IF( IERR.EQ.1 ) THEN
-                  INFO = 4
-               ELSE IF( IERR.EQ.3 ) THEN
-                  INFO = 13
-               END IF
-               RETURN
-            END IF
-C
-            WRKOPT = MAX( WRKOPT, DWORK(1) )
-         END IF
-      END IF
-C
-      NR = NRA + NU
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of AB09JD ***
-      END
--- a/extra/control-devel/src/AB09JV.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,958 +0,0 @@
-      SUBROUTINE AB09JV( JOB, DICO, JOBEV, STBCHK, N, M, P, NV, PV,
-     $                   A, LDA, B, LDB, C, LDC, D, LDD, AV, LDAV,
-     $                   EV, LDEV, BV, LDBV, CV, LDCV, DV, LDDV, IWORK,
-     $                   DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To construct a state-space representation (A,BS,CS,DS) of the
-C     projection of V*G or conj(V)*G containing the poles of G, from the
-C     state-space representations (A,B,C,D) and (AV-lambda*EV,BV,CV,DV),
-C     of the transfer-function matrices G and V, respectively.
-C     G is assumed to be a stable transfer-function matrix and
-C     the state matrix A must be in a real Schur form.
-C     When computing the stable projection of V*G, it is assumed
-C     that G and V have completely distinct poles.
-C     When computing the stable projection of conj(V)*G, it is assumed
-C     that G and conj(V) have completely distinct poles.
-C
-C     Note: For a transfer-function matrix G, conj(G) denotes the
-C     conjugate of G given by G'(-s) for a continuous-time system or
-C     G'(1/z) for a discrete-time system.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies the projection to be computed as follows:
-C             = 'V':  compute the projection of V*G containing
-C                     the poles of G;
-C             = 'C':  compute the projection of conj(V)*G containing
-C                     the poles of G.
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the systems as follows:
-C             = 'C':  G and V are continuous-time systems;
-C             = 'D':  G and V are discrete-time systems.
-C
-C     JOBEV   CHARACTER*1
-C             Specifies whether EV is a general square or an identity
-C             matrix as follows:
-C             = 'G':  EV is a general square matrix;
-C             = 'I':  EV is the identity matrix.
-C
-C     STBCHK  CHARACTER*1
-C             Specifies whether stability/antistability of V is to be
-C             checked as follows:
-C             = 'C':  check stability if JOB = 'C' or antistability if
-C                     JOB = 'V';
-C             = 'N':  do not check stability or antistability.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The dimension of the state vector of the system with
-C             the transfer-function matrix G.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The dimension of the input vector of the system with
-C             the transfer-function matrix G.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The dimension of the output vector of the system with the
-C             transfer-function matrix G, and also the dimension of
-C             the input vector if JOB = 'V', or of the output vector
-C             if JOB = 'C', of the system with the transfer-function
-C             matrix V.  P >= 0.
-C
-C     NV      (input) INTEGER
-C             The dimension of the state vector of the system with
-C             the transfer-function matrix V.  NV >= 0.
-C
-C     PV      (input) INTEGER
-C             The dimension of the output vector, if JOB = 'V', or
-C             of the input vector, if JOB = 'C', of the system with
-C             the transfer-function matrix V.  PV >= 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             state matrix A of the system with the transfer-function
-C             matrix G in a real Schur form.
-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
-C             the input/state matrix B of the system with the
-C             transfer-function matrix G. The matrix BS is equal to B.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the output matrix C of the system with the
-C             transfer-function matrix G.
-C             On exit, if INFO = 0, the leading PV-by-N part of this
-C             array contains the output matrix CS of the projection of
-C             V*G, if JOB = 'V', or of conj(V)*G, if JOB = 'C'.
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.  LDC >= MAX(1,P,PV).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the feedthrough matrix D of the system with the
-C             transfer-function matrix G.
-C             On exit, if INFO = 0, the leading PV-by-M part of
-C             this array contains the feedthrough matrix DS of the
-C             projection of V*G, if JOB = 'V', or of conj(V)*G,
-C             if JOB = 'C'.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.  LDD >= MAX(1,P,PV).
-C
-C     AV      (input/output) DOUBLE PRECISION array, dimension (LDAV,NV)
-C             On entry, the leading NV-by-NV part of this array must
-C             contain the state matrix AV of the system with the
-C             transfer-function matrix V.
-C             On exit, if INFO = 0, the leading NV-by-NV part of this
-C             array contains a condensed matrix as follows:
-C             if JOBEV = 'I', it contains the real Schur form of AV;
-C             if JOBEV = 'G' and JOB = 'V', it contains a quasi-upper
-C             triangular matrix representing the real Schur matrix
-C             in the real generalized Schur form of the pair (AV,EV);
-C             if JOBEV = 'G', JOB = 'C' and DICO = 'C', it contains a
-C             quasi-upper triangular matrix corresponding to the
-C             generalized real Schur form of the pair (AV',EV');
-C             if JOBEV = 'G', JOB = 'C' and DICO = 'D', it contains an
-C             upper triangular matrix corresponding to the generalized
-C             real Schur form of the pair (EV',AV').
-C
-C     LDAV    INTEGER
-C             The leading dimension of the array AV.  LDAV >= MAX(1,NV).
-C
-C     EV      (input/output) DOUBLE PRECISION array, dimension (LDEV,NV)
-C             On entry, if JOBEV = 'G', the leading NV-by-NV part of
-C             this array must contain the descriptor matrix EV of the
-C             system with the transfer-function matrix V.
-C             If JOBEV = 'I', EV is assumed to be an identity matrix
-C             and is not referenced.
-C             On exit, if INFO = 0 and JOBEV = 'G', the leading NV-by-NV
-C             part of this array contains a condensed matrix as follows:
-C             if JOB = 'V', it contains an upper triangular matrix
-C             corresponding to the real generalized Schur form of the
-C             pair (AV,EV);
-C             if JOB = 'C' and DICO = 'C', it contains an upper
-C             triangular matrix corresponding to the generalized real
-C             Schur form of the pair (AV',EV');
-C             if JOB = 'C' and DICO = 'D', it contains a quasi-upper
-C             triangular matrix corresponding to the generalized
-C             real Schur form of the pair (EV',AV').
-C
-C     LDEV    INTEGER
-C             The leading dimension of the array EV.
-C             LDEV >= MAX(1,NV), if JOBEV = 'G';
-C             LDEV >= 1,         if JOBEV = 'I'.
-C
-C     BV      (input/output) DOUBLE PRECISION array,
-C             dimension (LDBV,MBV), where MBV = P, if JOB = 'V', and
-C             MBV = PV, if JOB = 'C'.
-C             On entry, the leading NV-by-MBV part of this array must
-C             contain the input matrix BV of the system with the
-C             transfer-function matrix V.
-C             On exit, if INFO = 0, the leading NV-by-MBV part of this
-C             array contains Q'*BV, where Q is the orthogonal matrix
-C             that reduces AV to the real Schur form or the left
-C             orthogonal matrix used to reduce the pair (AV,EV),
-C             (AV',EV') or (EV',AV') to the generalized real Schur form.
-C
-C     LDBV    INTEGER
-C             The leading dimension of the array BV.  LDBV >= MAX(1,NV).
-C
-C     CV      (input/output) DOUBLE PRECISION array, dimension (LDCV,NV)
-C             On entry, the leading PCV-by-NV part of this array must
-C             contain the output matrix CV of the system with the
-C             transfer-function matrix V, where PCV = PV, if JOB = 'V',
-C             or PCV = P, if JOB = 'C'.
-C             On exit, if INFO = 0, the leading PCV-by-NV part of this
-C             array contains CV*Q, where Q is the orthogonal matrix that
-C             reduces AV to the real Schur form, or CV*Z, where Z is the
-C             right orthogonal matrix used to reduce the pair (AV,EV),
-C             (AV',EV') or (EV',AV') to the generalized real Schur form.
-C
-C     LDCV    INTEGER
-C             The leading dimension of the array CV.
-C             LDCV >= MAX(1,PV) if JOB = 'V';
-C             LDCV >= MAX(1,P)  if JOB = 'C'.
-C
-C     DV      (input) DOUBLE PRECISION array,
-C             dimension (LDDV,MBV), where MBV = P, if JOB = 'V', and
-C             MBV = PV, if JOB = 'C'.
-C             The leading PCV-by-MBV part of this array must contain
-C             the feedthrough matrix DV of the system with the
-C             transfer-function matrix V, where PCV = PV, if JOB = 'V',
-C             or PCV = P, if JOB = 'C'.
-C
-C     LDDV    INTEGER
-C             The leading dimension of the array DV.
-C             LDDV >= MAX(1,PV) if JOB = 'V';
-C             LDDV >= MAX(1,P)  if JOB = 'C'.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK =   0,    if JOBEV = 'I';
-C             LIWORK = NV+N+6, if JOBEV = 'G'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= LW1, if JOBEV = 'I',
-C             LDWORK >= LW2, if JOBEV = 'G', where
-C               LW1 = MAX( 1, NV*(NV+5), NV*N + MAX( a, PV*N, PV*M ) )
-C                     a = 0,    if DICO = 'C' or  JOB = 'V',
-C                     a = 2*NV, if DICO = 'D' and JOB = 'C';
-C               LW2 = MAX( 2*NV*NV + MAX( 11*NV+16, P*NV, PV*NV ),
-C                          NV*N + MAX( NV*N+N*N, PV*N, PV*M ) ).
-C             For good 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:  the reduction of the pair (AV,EV) to the real
-C                    generalized Schur form failed (JOBEV = 'G'),
-C                    or the reduction of the matrix AV to the real
-C                    Schur form failed (JOBEV = 'I);
-C             =  2:  the solution of the Sylvester equation failed
-C                    because the matrix A and the pencil AV-lambda*EV
-C                    have common eigenvalues (if JOB = 'V'), or the
-C                    pencil -AV-lambda*EV and A have common eigenvalues
-C                    (if JOB = 'C' and DICO = 'C'), or the pencil
-C                    AV-lambda*EV has an eigenvalue which is the
-C                    reciprocal of one of eigenvalues of A
-C                    (if JOB = 'C' and DICO = 'D');
-C             =  3:  the solution of the Sylvester equation failed
-C                    because the matrices A and AV have common
-C                    eigenvalues (if JOB = 'V'), or the matrices A
-C                    and -AV have common eigenvalues (if JOB = 'C' and
-C                    DICO = 'C'), or the matrix A has an eigenvalue
-C                    which is the reciprocal of one of eigenvalues of AV
-C                    (if JOB = 'C' and DICO = 'D');
-C             =  4:  JOB = 'V' and the pair (AV,EV) has not completely
-C                    unstable generalized eigenvalues, or JOB = 'C' and
-C                    the pair (AV,EV) has not completely stable
-C                    generalized eigenvalues.
-C
-C     METHOD
-C
-C     If JOB = 'V', the matrices of the stable projection of V*G are
-C     computed as
-C
-C       BS = B,  CS = CV*X + DV*C,  DS = DV*D,
-C
-C     where X satisfies the generalized Sylvester equation
-C
-C       AV*X - EV*X*A + BV*C = 0.
-C
-C     If JOB = 'C', the matrices of the stable projection of conj(V)*G
-C     are computed using the following formulas:
-C
-C     - for a continuous-time system, the matrices BS, CS and DS of
-C       the stable projection are computed as
-C
-C         BS = B,  CS = BV'*X + DV'*C,  DS = DV'*D,
-C
-C       where X satisfies the generalized Sylvester equation
-C
-C         AV'*X + EV'*X*A + CV'*C = 0.
-C
-C     - for a discrete-time system, the matrices BS, CS and DS of
-C       the stable projection are computed as
-C
-C         BS = B,  CS = BV'*X*A + DV'*C,  DS = DV'*D + BV'*X*B,
-C
-C       where X satisfies the generalized Sylvester equation
-C
-C         EV'*X - AV'*X*A = CV'*C.
-C
-C     REFERENCES
-C
-C     [1] Varga, A.
-C         Efficient and numerically reliable implementation of the
-C         frequency-weighted Hankel-norm approximation model reduction
-C         approach.
-C         Proc. 2001 ECC, Porto, Portugal, 2001.
-C
-C     [2] Zhou, K.
-C         Frequency-weighted H-infinity norm and optimal Hankel norm
-C         model reduction.
-C         IEEE Trans. Autom. Control, vol. 40, pp. 1687-1699, 1995.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on numerically stable algorithms.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, July 2000.
-C     D. Sima, University of Bucharest, March 2001.
-C     V. Sima, Research Institute for Informatics, Bucharest, Mar. 2001.
-C
-C     REVISIONS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, May 2001.
-C     V. Sima, Research Institute for Informatics, Bucharest, June 2001.
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, Nov. 2003.
-C
-C     KEYWORDS
-C
-C     Frequency weighting, model reduction, multivariable system,
-C     state-space model, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, JOB, JOBEV, STBCHK
-      INTEGER           INFO, LDA, LDAV, LDB, LDBV, LDC, LDCV,
-     $                  LDD, LDDV, LDEV, LDWORK, M, N, NV, P, PV
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), AV(LDAV,*), B(LDB,*), BV(LDBV,*),
-     $                  C(LDC,*), CV(LDCV,*), D(LDD,*), DV(LDDV,*),
-     $                  DWORK(*), EV(LDEV,*)
-C     .. Local Scalars ..
-      CHARACTER*1       EVTYPE, STDOM
-      LOGICAL           CONJS, DISCR, STABCK, UNITEV
-      DOUBLE PRECISION  ALPHA, DIF, SCALE, TOLINF, WORK
-      INTEGER           I, IA, IERR, KAI, KAR, KB, KC, KE, KF, KQ, KW,
-     $                  KZ, LDW, LDWN, LW, SDIM
-C     .. Local Arrays ..
-      LOGICAL           BWORK(1)
-C     .. External Functions ..
-      LOGICAL           DELCTG, LSAME
-      DOUBLE PRECISION  DLAMCH, DLANGE
-      EXTERNAL          DELCTG, DLAMCH, DLANGE, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB09JX, DGEMM, DGGES, DLACPY, DLASET, DSWAP,
-     $                  DTGSYL, DTRSYL, SB04PY, TB01WD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, MAX, SQRT
-C
-C     .. Executable Statements ..
-C
-      CONJS  = LSAME( JOB,    'C' )
-      DISCR  = LSAME( DICO,   'D' )
-      UNITEV = LSAME( JOBEV,  'I' )
-      STABCK = LSAME( STBCHK, 'C' )
-C
-      INFO = 0
-      IF( UNITEV ) THEN
-         IF ( DISCR .AND. CONJS ) THEN
-            IA = 2*NV
-         ELSE
-            IA = 0
-         END IF
-         LW = MAX( 1, NV*( NV + 5 ), NV*N + MAX( IA, PV*N, PV*M ) )
-      ELSE
-         LW = MAX( 2*NV*NV + MAX( 11*NV+16, P*NV, PV*NV ),
-     $             NV*N + MAX( NV*N + N*N, PV*N, PV*M ) )
-      END IF
-C
-C     Test the input scalar arguments.
-C
-      LDWN = MAX( 1, N )
-      LDW  = MAX( 1, NV )
-      IF( .NOT. ( LSAME( JOB, 'V' ) .OR. CONJS ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( LSAME( DICO,  'C' ) .OR. DISCR  ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( LSAME( JOBEV, 'G' ) .OR. UNITEV ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT. ( LSAME( STBCHK, 'N' ) .OR. STABCK ) ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( NV.LT.0 ) THEN
-         INFO = -8
-      ELSE IF( PV.LT.0 ) THEN
-         INFO = -9
-      ELSE IF( LDA.LT.LDWN ) THEN
-         INFO = -11
-      ELSE IF( LDB.LT.LDWN ) THEN
-         INFO = -13
-      ELSE IF( LDC.LT.MAX( 1, P, PV ) ) THEN
-         INFO = -15
-      ELSE IF( LDD.LT.MAX( 1, P, PV ) ) THEN
-         INFO = -17
-      ELSE IF( LDAV.LT.LDW ) THEN
-         INFO = -19
-      ELSE IF( LDEV.LT.1 .OR. ( .NOT.UNITEV .AND. LDEV.LT.NV ) ) THEN
-         INFO = -21
-      ELSE IF( LDBV.LT.LDW ) THEN
-         INFO = -23
-      ELSE IF( ( .NOT.CONJS .AND. LDCV.LT.MAX( 1, PV ) ) .OR.
-     $         (      CONJS .AND. LDCV.LT.MAX( 1, P  ) ) ) THEN
-         INFO = -25
-      ELSE IF( ( .NOT.CONJS .AND. LDDV.LT.MAX( 1, PV ) ) .OR.
-     $         (      CONJS .AND. LDDV.LT.MAX( 1, P  ) ) ) THEN
-         INFO = -27
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -30
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09JV', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( P.EQ.0 .OR. PV.EQ.0 ) THEN
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Set options for stability/antistability checking.
-C
-      IF( DISCR ) THEN
-         ALPHA = ONE
-      ELSE
-         ALPHA = ZERO
-      END IF
-C
-      WORK = ONE
-      TOLINF = DLAMCH( 'Epsilon' )
-C
-      IF( UNITEV ) THEN
-C
-C        EV is the identity matrix.
-C
-         IF( NV.GT.0 ) THEN
-C
-C           Reduce AV to the real Schur form using an orthogonal
-C           similarity transformation AV <- Q'*AV*Q and apply the
-C           transformation to BV and CV: BV <- Q'*BV and CV <- CV*Q.
-C
-C           Workspace needed:  NV*(NV+5);
-C                              prefer larger.
-C
-            KW = NV*( NV + 2 ) + 1
-            IF( CONJS ) THEN
-               STDOM = 'S'
-               ALPHA = ALPHA + SQRT( TOLINF )
-               CALL TB01WD( NV, PV, P, AV, LDAV, BV, LDBV, CV, LDCV,
-     $                      DWORK(2*NV+1), NV, DWORK, DWORK(NV+1),
-     $                      DWORK(KW), LDWORK-KW+1, IERR )
-            ELSE
-               STDOM = 'U'
-               ALPHA = ALPHA - SQRT( TOLINF )
-               CALL TB01WD( NV, P, PV, AV, LDAV, BV, LDBV, CV, LDCV,
-     $                      DWORK(2*NV+1), NV, DWORK, DWORK(NV+1),
-     $                      DWORK(KW), LDWORK-KW+1, IERR )
-            END IF
-            IF( IERR.NE.0 ) THEN
-               INFO = 1
-               RETURN
-            END IF
-            IF( STABCK ) THEN
-C
-C              Check stability/antistability of eigenvalues of AV.
-C
-               CALL AB09JX( DICO, STDOM, 'S', NV, ALPHA, DWORK,
-     $                      DWORK(NV+1), DWORK, TOLINF, IERR )
-               IF( IERR.NE.0 ) THEN
-                  INFO = 4
-                  RETURN
-               END IF
-            END IF
-C
-            WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-C
-         END IF
-C
-         KW = NV*N + 1
-         IF( CONJS ) THEN
-C
-C           Compute the projection of conj(V)*G.
-C
-C           Total workspace needed:  NV*N + MAX( a, PV*N, PV*M ), where
-C                                    a = 0,    if DICO = 'C',
-C                                    a = 2*NV, if DICO = 'D'.
-C
-C           Compute -CV'*C.
-C           Workspace needed: NV*N.
-C
-            CALL DGEMM( 'T', 'N', NV, N, P, -ONE, CV, LDCV, C, LDC,
-     $                  ZERO, DWORK, LDW )
-C
-            IF( DISCR ) THEN
-C
-C              Compute X and SCALE satisfying
-C
-C              AV'*X*A - X = -SCALE*CV'*C.
-C
-C              Additional workspace needed: 2*NV.
-C
-               CALL SB04PY( 'T', 'N', -1, NV, N, AV, LDAV, A, LDA,
-     $                      DWORK, LDW, SCALE, DWORK(KW), IERR )
-               IF( IERR.NE.0 ) THEN
-                  INFO = 3
-                  RETURN
-               END IF
-C
-C              Construct CS = DV'*C + BV'*X*A/SCALE,
-C                        DS = DV'*D + BV'*X*B/SCALE.
-C
-C              Additional workspace needed: MAX( PV*N, PV*M ).
-C
-C              C <- DV'*C.
-C
-               CALL DGEMM( 'T', 'N', PV, N, P, ONE, DV, LDDV, C, LDC,
-     $                     ZERO, DWORK(KW), PV )
-               CALL DLACPY( 'Full', PV, N, DWORK(KW), PV, C, LDC )
-C
-C              D <- DV'*D.
-C
-               CALL DGEMM( 'T', 'N', PV, M, P, ONE, DV, LDDV, D, LDD,
-     $                     ZERO, DWORK(KW), PV )
-               CALL DLACPY( 'Full', PV, M, DWORK(KW), PV, D, LDD )
-C
-C              C <- C + BV'*X*A/SCALE.
-C
-               CALL DGEMM( 'T', 'N', PV, N, NV, ONE / SCALE, BV, LDBV,
-     $                     DWORK, LDW, ZERO, DWORK(KW), PV )
-               CALL DGEMM( 'N', 'N', PV, N, N, ONE, DWORK(KW), PV,
-     $                     A, LDA, ONE, C, LDC )
-C
-C              D <- D + BV'*X*B/SCALE.
-C
-               CALL DGEMM( 'N', 'N', PV, M, N, ONE, DWORK(KW), PV,
-     $                     B, LDB, ONE, D, LDD )
-            ELSE
-C
-C              Compute X and SCALE satisfying
-C
-C              AV'*X + X*A + SCALE*CV'*C = 0.
-C
-               IF( N.GT.0 ) THEN
-                  CALL DTRSYL( 'T', 'N', 1, NV, N, AV, LDAV, A, LDA,
-     $                         DWORK, LDW, SCALE, IERR )
-                  IF( IERR.NE.0 ) THEN
-                     INFO = 3
-                     RETURN
-                  END IF
-               END IF
-C
-C              Construct CS = DV'*C + BV'*X/SCALE,
-C                        DS = DV'*D.
-C              Additional workspace needed: MAX( PV*N, PV*M ).
-C
-C              Construct C <- DV'*C + BV'*X/SCALE.
-C
-               CALL DGEMM( 'T', 'N', PV, N, P, ONE, DV, LDDV, C, LDC,
-     $                     ZERO, DWORK(KW), PV )
-               CALL DLACPY( 'Full', PV, N, DWORK(KW), PV, C, LDC )
-               CALL DGEMM( 'T', 'N', PV, N, NV, ONE / SCALE, BV, LDBV,
-     $                     DWORK, LDW, ONE, C, LDC )
-C
-C              Construct D <- DV'*D.
-C
-               CALL DGEMM( 'T', 'N', PV, M, P, ONE, DV, LDDV, D, LDD,
-     $                     ZERO, DWORK(KW), PV )
-               CALL DLACPY( 'Full', PV, M, DWORK(KW), PV, D, LDD )
-            END IF
-         ELSE
-C
-C           Compute the projection of V*G.
-C
-C           Total workspace needed:  NV*N + MAX( PV*N, PV*M ).
-C
-C           Compute -BV*C.
-C           Workspace needed: NV*N.
-C
-            CALL DGEMM( 'N', 'N', NV, N, P, -ONE, BV, LDBV, C, LDC,
-     $                  ZERO, DWORK, LDW )
-C
-C           Compute X and SCALE satisfying
-C
-C           AV*X - X*A + SCALE*BV*C = 0.
-C
-            IF( N.GT.0 ) THEN
-               CALL DTRSYL( 'N', 'N', -1, NV, N, AV, LDAV, A, LDA,
-     $                      DWORK, LDW, SCALE, IERR )
-               IF( IERR.NE.0 ) THEN
-                  INFO = 3
-                  RETURN
-               END IF
-            END IF
-C
-C           Construct CS = DV*C + CV*X/SCALE,
-C                     DS = DV*D.
-C           Additional workspace needed: MAX( PV*N, PV*M ).
-C
-C           Construct C <- DV*C + CV*X/SCALE.
-C
-            CALL DGEMM( 'N', 'N', PV, N, P, ONE, DV, LDDV, C, LDC,
-     $                  ZERO, DWORK(KW), PV )
-            CALL DLACPY( 'Full', PV, N, DWORK(KW), PV, C, LDC )
-            CALL DGEMM( 'N', 'N', PV, N, NV, ONE / SCALE, CV, LDCV,
-     $                  DWORK, LDW, ONE, C, LDC )
-C
-C           Construct D <- DV*D.
-C
-            CALL DGEMM( 'N', 'N', PV, M, P, ONE, DV, LDDV, D, LDD,
-     $                  ZERO, DWORK(KW), PV )
-            CALL DLACPY( 'Full', PV, M, DWORK(KW), PV, D, LDD )
-         END IF
-      ELSE
-C
-C        EV is a general matrix.
-C
-         IF( NV.GT.0 ) THEN
-            TOLINF = TOLINF * DLANGE( '1', NV, NV, EV, LDEV, DWORK )
-C
-C           Reduce (AV,EV), or (AV',EV') or (EV',AV') to a generalized
-C           real Schur form using an orthogonal equivalence
-C           transformation and apply the orthogonal transformation
-C           appropriately to BV and CV, or CV' and BV'.
-C
-C           Workspace needed:  2*NV*NV + MAX( 11*NV+16, NV*P, NV*PV );
-C                              prefer larger.
-C
-            KQ  = 1
-            KZ  = KQ  + NV*NV
-            KAR = KZ  + NV*NV
-            KAI = KAR + NV
-            KB  = KAI + NV
-            KW  = KB  + NV
-C
-            IF( CONJS ) THEN
-               STDOM = 'S'
-               ALPHA = ALPHA + SQRT( TOLINF )
-C
-C              Transpose AV and EV, if non-scalar.
-C
-               DO 10 I = 1, NV - 1
-                  CALL DSWAP( NV-I, AV(I+1,I), 1, AV(I,I+1), LDAV )
-                  CALL DSWAP( NV-I, EV(I+1,I), 1, EV(I,I+1), LDEV )
-   10          CONTINUE
-C
-               IF( DISCR ) THEN
-C
-C                 Reduce (EV',AV') to a generalized real Schur form
-C                 using orthogonal transformation matrices Q and Z
-C                 such that Q'*EV'*Z results in a quasi-triangular form
-C                 and Q'*AV'*Z results upper triangular.
-C                 Total workspace needed: 2*NV*NV + 11*NV + 16.
-C
-                  EVTYPE = 'R'
-                  CALL DGGES( 'Vectors', 'Vectors', 'Not ordered',
-     $                        DELCTG, NV, EV, LDEV, AV, LDAV, SDIM,
-     $                        DWORK(KAR), DWORK(KAI), DWORK(KB),
-     $                        DWORK(KQ), LDW, DWORK(KZ), LDW,
-     $                        DWORK(KW), LDWORK-KW+1, BWORK, IERR )
-               ELSE
-C
-C                 Reduce (AV',EV') to a generalized real Schur form
-C                 using orthogonal transformation matrices Q and Z
-C                 such that Q'*AV'*Z results in a quasi-triangular form
-C                 and Q'*EV'*Z results upper triangular.
-C                 Total workspace needed: 2*NV*NV + 11*NV + 16.
-C
-                  EVTYPE = 'G'
-                  CALL DGGES( 'Vectors', 'Vectors', 'Not ordered',
-     $                        DELCTG, NV, AV, LDAV, EV, LDEV, SDIM,
-     $                        DWORK(KAR), DWORK(KAI), DWORK(KB),
-     $                        DWORK(KQ), LDW, DWORK(KZ), LDW,
-     $                        DWORK(KW), LDWORK-KW+1, BWORK, IERR )
-               END IF
-               IF( IERR.NE.0 ) THEN
-                  INFO = 1
-                  RETURN
-               END IF
-               IF( STABCK ) THEN
-C
-C                 Check stability/antistability of generalized
-C                 eigenvalues of the pair (AV,EV).
-C
-                  CALL AB09JX( DICO, STDOM, EVTYPE, NV, ALPHA,
-     $                         DWORK(KAR), DWORK(KAI), DWORK(KB),
-     $                         TOLINF, IERR )
-                  IF( IERR.NE.0 ) THEN
-                     INFO = 4
-                     RETURN
-                  END IF
-               END IF
-               WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-C
-C              Compute Z'*BV and CV*Q.
-C              Total workspace needed: 2*NV*NV + NV*MAX(P,PV).
-C
-               KW = KAR
-               CALL DLACPY( 'Full', NV, PV, BV, LDBV, DWORK(KW), LDW )
-               CALL DGEMM( 'T', 'N', NV, PV, NV, ONE, DWORK(KZ), LDW,
-     $                     DWORK(KW), LDW, ZERO, BV, LDBV )
-               CALL DLACPY( 'Full', P, NV, CV, LDCV, DWORK(KW), P )
-               CALL DGEMM( 'N', 'N', P, NV, NV, ONE, DWORK(KW), P,
-     $                     DWORK(KQ), LDW, ZERO, CV, LDCV )
-            ELSE
-C
-C              Reduce (AV,EV) to a generalized real Schur form
-C              using orthogonal transformation matrices Q and Z
-C              such that Q'*AV*Z results in a quasi-triangular form
-C              and Q'*EV*Z results upper triangular.
-C              Total workspace needed: 2*NV*NV + 11*NV + 16.
-C
-               STDOM  = 'U'
-               EVTYPE = 'G'
-               ALPHA  = ALPHA - SQRT( TOLINF )
-               CALL DGGES( 'Vectors', 'Vectors', 'Not ordered',
-     $                     DELCTG, NV, AV, LDAV, EV, LDEV, SDIM,
-     $                     DWORK(KAR), DWORK(KAI), DWORK(KB),
-     $                     DWORK(KQ), LDW, DWORK(KZ), LDW,
-     $                     DWORK(KW), LDWORK-KW+1, BWORK, IERR )
-               IF( IERR.NE.0 ) THEN
-                  INFO = 1
-                  RETURN
-               END IF
-               IF( STABCK ) THEN
-C
-C                 Check stability/antistability of generalized
-C                 eigenvalues of the pair (AV,EV).
-C
-                  CALL AB09JX( DICO, STDOM, EVTYPE, NV, ALPHA,
-     $                         DWORK(KAR), DWORK(KAI), DWORK(KB),
-     $                         TOLINF, IERR )
-                  IF( IERR.NE.0 ) THEN
-                     INFO = 4
-                     RETURN
-                  END IF
-               END IF
-               WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-C
-C              Compute Q'*BV and CV*Z.
-C              Total workspace needed: 2*NV*NV + NV*MAX(P,PV).
-C
-               KW = KAR
-               CALL DLACPY( 'Full', NV, P, BV, LDBV, DWORK(KW), LDW )
-               CALL DGEMM( 'T', 'N', NV, P, NV, ONE, DWORK(KQ), LDW,
-     $                     DWORK(KW), LDW, ZERO, BV, LDBV )
-               CALL DLACPY( 'Full', PV, NV, CV, LDCV, DWORK(KW), PV )
-               CALL DGEMM( 'N', 'N', PV, NV, NV, ONE, DWORK(KW), PV,
-     $                     DWORK(KZ), LDW, ZERO, CV, LDCV )
-            END IF
-            WORK = MAX( WORK, DBLE( 2*NV*NV + NV*MAX( P, PV ) ) )
-C
-         END IF
-C
-         KC = 1
-         KF = KC + NV*N
-         KE = KF + NV*N
-         KW = KE + N*N
-         CALL DLASET( 'Full', NV, N, ZERO, ZERO, DWORK(KF), LDW )
-C
-         IF( CONJS ) THEN
-C
-C           Compute the projection of conj(V)*G.
-C
-C           Total workspace needed: NV*N + MAX( NV*N+N*N, PV*N, PV*M )
-C
-C           Compute CV'*C.
-C           Workspace needed: NV*N.
-C
-            CALL DGEMM( 'T', 'N', NV, N, P, ONE, CV, LDCV, C, LDC,
-     $                  ZERO, DWORK(KC), LDW )
-C
-            IF( DISCR ) THEN
-C
-C              Compute X and SCALE satisfying
-C
-C              EV'*X - AV'*X*A = SCALE*CV'*C by solving equivalently
-C
-C              EV'*X - Y*A = SCALE*CV'*C,
-C              AV'*X - Y   = 0.
-C
-C              Additional workspace needed:
-C              real    NV*N + N*N;
-C              integer NV+N+6.
-C
-               IF( N.GT.0 ) THEN
-                  CALL DLASET( 'Full', N, N, ZERO, ONE, DWORK(KE), LDWN
-     $                       )
-                  CALL DTGSYL( 'N', 0, NV, N, EV, LDEV, A, LDA,
-     $                         DWORK(KC), LDW, AV, LDAV, DWORK(KE),
-     $                         LDWN, DWORK(KF), LDW, SCALE, DIF,
-     $                         DWORK(KW), LDWORK-KW+1, IWORK, IERR )
-                  IF( IERR.NE.0 ) THEN
-                     INFO = 2
-                     RETURN
-                  END IF
-               END IF
-C
-C              Construct C <- DV'*C + BV'*X*A/SCALE,
-C                        D <- DV'*D + BV'*X*B/SCALE.
-C
-C              Additional workspace needed: MAX( PV*N, PV*M ).
-C
-C              C <- DV'*C.
-C
-               KW = KF
-               CALL DGEMM( 'T', 'N', PV, N, P, ONE, DV, LDDV, C, LDC,
-     $                     ZERO, DWORK(KW), PV )
-               CALL DLACPY( 'Full', PV, N, DWORK(KW), PV, C, LDC )
-C
-C              D <- DV'*D.
-C
-               CALL DGEMM( 'T', 'N', PV, M, P, ONE, DV, LDDV, D, LDD,
-     $                     ZERO, DWORK(KW), PV )
-               CALL DLACPY( 'Full', PV, M, DWORK(KW), PV, D, LDD )
-C
-C              C <- C + BV'*X*A/SCALE.
-C
-               CALL DGEMM( 'T', 'N', PV, N, NV, ONE / SCALE, BV, LDBV,
-     $                     DWORK(KC), LDW, ZERO, DWORK(KW), PV )
-               CALL DGEMM( 'N', 'N', PV, N, N, ONE, DWORK(KW), PV,
-     $                     A, LDA, ONE, C, LDC )
-C
-C              D <- D + BV'*X*B/SCALE.
-C
-               CALL DGEMM( 'N', 'N', PV, M, N, ONE, DWORK(KW), PV,
-     $                     B, LDB, ONE, D, LDD )
-            ELSE
-C
-C              Compute X and SCALE satisfying
-C
-C              AV'*X + EV'*X*A + SCALE*CV'*C = 0 by solving equivalently
-C
-C              AV'*X - Y*A    = -SCALE*CV'*C,
-C              EV'*X - Y*(-I) = 0.
-C
-C              Additional workspace needed:
-C              real    NV*N+N*N;
-C              integer NV+N+6.
-C
-               IF( N.GT.0 ) THEN
-                  CALL DLASET( 'Full', N, N, ZERO, -ONE, DWORK(KE), LDWN
-     $                       )
-                  CALL DTGSYL( 'N', 0, NV, N, AV, LDAV, A, LDA,
-     $                         DWORK(KC), LDW, EV, LDEV, DWORK(KE),
-     $                         LDWN, DWORK(KF), LDW, SCALE, DIF,
-     $                         DWORK(KW), LDWORK-KW+1, IWORK, IERR )
-C
-C                 Note that the computed solution in DWORK(KC) is -X.
-C
-                  IF( IERR.NE.0 ) THEN
-                     INFO = 2
-                     RETURN
-                  END IF
-               END IF
-C
-C              Construct C <- DV'*C + BV'*X/SCALE.
-C
-               KW = KF
-               CALL DGEMM( 'T', 'N', PV, N, P, ONE, DV, LDDV, C, LDC,
-     $                     ZERO, DWORK(KW), PV )
-               CALL DLACPY( 'Full', PV, N, DWORK(KW), PV, C, LDC )
-               CALL DGEMM( 'T', 'N', PV, N, NV, -ONE / SCALE, BV, LDBV,
-     $                     DWORK(KC), LDW, ONE, C, LDC )
-C
-C              Construct D <- DV'*D.
-C
-               CALL DGEMM( 'T', 'N', PV, M, P, ONE, DV, LDDV, D, LDD,
-     $                     ZERO, DWORK(KW), PV )
-               CALL DLACPY( 'Full', PV, M, DWORK(KW), PV, D, LDD )
-            END IF
-         ELSE
-C
-C           Compute the projection of V*G.
-C
-C           Total workspace needed: NV*N + MAX( NV*N+N*N, PV*N, PV*M )
-C
-C           Compute -BV*C.
-C           Workspace needed: NV*N.
-C
-            CALL DGEMM( 'N', 'N', NV, N, P, -ONE, BV, LDBV, C, LDC,
-     $                  ZERO, DWORK, LDW )
-C
-C           Compute X and SCALE satisfying
-C
-C           AV*X - EV*X*A + SCALE*BV*C = 0 by solving equivalently
-C
-C           AV*X - Y*A = -SCALE*BV*C,
-C           EV*X - Y   = 0.
-C
-C           Additional workspace needed:
-C           real    NV*N + N*N;
-C           integer NV+N+6.
-C
-            IF( N.GT.0 ) THEN
-               CALL DLASET( 'Full', N, N, ZERO, ONE, DWORK(KE), LDWN )
-               CALL DTGSYL( 'N', 0, NV, N, AV, LDAV, A, LDA,
-     $                      DWORK(KC), LDW, EV, LDEV, DWORK(KE), LDWN,
-     $                      DWORK(KF), LDW, SCALE, DIF, DWORK(KW),
-     $                      LDWORK-KW+1, IWORK, IERR )
-               IF( IERR.NE.0 ) THEN
-                  INFO = 2
-                  RETURN
-               END IF
-            END IF
-C
-C           Construct C <- DV*C + CV*X/SCALE.
-C
-            KW = KF
-            CALL DGEMM( 'N', 'N', PV, N, P, ONE, DV, LDDV, C, LDC,
-     $                  ZERO, DWORK(KW), PV )
-            CALL DLACPY( 'Full', PV, N, DWORK(KW), PV, C, LDC )
-            CALL DGEMM( 'N', 'N', PV, N, NV, ONE / SCALE, CV, LDCV,
-     $                  DWORK, LDW, ONE, C, LDC )
-C
-C           Construct D <- DV*D.
-C
-            CALL DGEMM( 'N', 'N', PV, M, P, ONE, DV, LDDV, D, LDD,
-     $                  ZERO, DWORK(KW), PV )
-            CALL DLACPY( 'Full', PV, M, DWORK(KW), PV, D, LDD )
-         END IF
-      END IF
-C
-      DWORK(1) = MAX( WORK, DBLE( LW ) )
-C
-      RETURN
-C *** Last line of AB09JV ***
-      END
--- a/extra/control-devel/src/AB09JW.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,972 +0,0 @@
-      SUBROUTINE AB09JW( JOB, DICO, JOBEW, STBCHK, N, M, P, NW, MW,
-     $                   A, LDA, B, LDB, C, LDC, D, LDD, AW, LDAW,
-     $                   EW, LDEW, BW, LDBW, CW, LDCW, DW, LDDW, IWORK,
-     $                   DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To construct a state-space representation (A,BS,CS,DS) of the
-C     projection of G*W or G*conj(W) containing the poles of G, from the
-C     state-space representations (A,B,C,D) and (AW-lambda*EW,BW,CW,DW),
-C     of the transfer-function matrices G and W, respectively.
-C     G is assumed to be a stable transfer-function matrix and
-C     the state matrix A must be in a real Schur form.
-C     When computing the stable projection of G*W, it is assumed
-C     that G and W have completely distinct poles.
-C     When computing the stable projection of G*conj(W), it is assumed
-C     that G and conj(W) have completely distinct poles.
-C
-C     Note: For a transfer-function matrix G, conj(G) denotes the
-C     conjugate of G given by G'(-s) for a continuous-time system or
-C     G'(1/z) for a discrete-time system.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies the projection to be computed as follows:
-C             = 'W':  compute the projection of G*W containing
-C                     the poles of G;
-C             = 'C':  compute the projection of G*conj(W) containing
-C                     the poles of G.
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the systems as follows:
-C             = 'C':  G and W are continuous-time systems;
-C             = 'D':  G and W are discrete-time systems.
-C
-C     JOBEW   CHARACTER*1
-C             Specifies whether EW is a general square or an identity
-C             matrix as follows:
-C             = 'G':  EW is a general square matrix;
-C             = 'I':  EW is the identity matrix.
-C
-C     STBCHK  CHARACTER*1
-C             Specifies whether stability/antistability of W is to be
-C             checked as follows:
-C             = 'C':  check stability if JOB = 'C' or antistability if
-C                     JOB = 'W';
-C             = 'N':  do not check stability or antistability.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The dimension of the state vector of the system with
-C             the transfer-function matrix G.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The dimension of the input vector of the system with
-C             the transfer-function matrix G, and also the dimension
-C             of the output vector if JOB = 'W', or of the input vector
-C             if JOB = 'C', of the system with the transfer-function
-C             matrix W.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The dimension of the output vector of the system with the
-C             transfer-function matrix G.  P >= 0.
-C
-C     NW      (input) INTEGER
-C             The dimension of the state vector of the system with the
-C             transfer-function matrix W.  NW >= 0.
-C
-C     MW      (input) INTEGER
-C             The dimension of the input vector, if JOB = 'W', or of
-C             the output vector, if JOB = 'C', of the system with the
-C             transfer-function matrix W.  MW >= 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             state matrix A of the system with the transfer-function
-C             matrix G in a real Schur form.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array,
-C             dimension (LDB,MAX(M,MW))
-C             On entry, the leading N-by-M part of this array must
-C             contain the input matrix B of the system with the
-C             transfer-function matrix G.
-C             On exit, if INFO = 0, the leading N-by-MW part of this
-C             array contains the input matrix BS of the projection of
-C             G*W, if JOB = 'W', or of G*conj(W), if JOB = 'C'.
-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 P-by-N part of this array must contain
-C             the output/state matrix C of the system with the
-C             transfer-function matrix G. The matrix CS is equal to C.
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array,
-C             dimension (LDB,MAX(M,MW))
-C             On entry, the leading P-by-M part of this array must
-C             contain the feedthrough matrix D of the system with
-C             the transfer-function matrix G.
-C             On exit, if INFO = 0, the leading P-by-MW part of
-C             this array contains the feedthrough matrix DS of the
-C             projection of G*W, if JOB = 'W', or of G*conj(W),
-C             if JOB = 'C'.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.  LDD >= MAX(1,P).
-C
-C     AW      (input/output) DOUBLE PRECISION array, dimension (LDAW,NW)
-C             On entry, the leading NW-by-NW part of this array must
-C             contain the state matrix AW of the system with the
-C             transfer-function matrix W.
-C             On exit, if INFO = 0, the leading NW-by-NW part of this
-C             array contains a condensed matrix as follows:
-C             if JOBEW = 'I', it contains the real Schur form of AW;
-C             if JOBEW = 'G' and JOB = 'W', it contains a quasi-upper
-C             triangular matrix representing the real Schur matrix
-C             in the real generalized Schur form of the pair (AW,EW);
-C             if JOBEW = 'G', JOB = 'C' and DICO = 'C', it contains a
-C             quasi-upper triangular matrix corresponding to the
-C             generalized real Schur form of the pair (AW',EW');
-C             if JOBEW = 'G', JOB = 'C' and DICO = 'D', it contains an
-C             upper triangular matrix corresponding to the generalized
-C             real Schur form of the pair (EW',AW').
-C
-C     LDAW    INTEGER
-C             The leading dimension of the array AW.  LDAW >= MAX(1,NW).
-C
-C     EW      (input/output) DOUBLE PRECISION array, dimension (LDEW,NW)
-C             On entry, if JOBEW = 'G', the leading NW-by-NW part of
-C             this array must contain the descriptor matrix EW of the
-C             system with the transfer-function matrix W.
-C             If JOBEW = 'I', EW is assumed to be an identity matrix
-C             and is not referenced.
-C             On exit, if INFO = 0 and JOBEW = 'G', the leading NW-by-NW
-C             part of this array contains a condensed matrix as follows:
-C             if JOB = 'W', it contains an upper triangular matrix
-C             corresponding to the real generalized Schur form of the
-C             pair (AW,EW);
-C             if JOB = 'C' and DICO = 'C', it contains an upper
-C             triangular matrix corresponding to the generalized real
-C             Schur form of the pair (AW',EW');
-C             if JOB = 'C' and DICO = 'D', it contains a quasi-upper
-C             triangular matrix corresponding to the generalized
-C             real Schur form of the pair (EW',AW').
-C
-C     LDEW    INTEGER
-C             The leading dimension of the array EW.
-C             LDEW >= MAX(1,NW), if JOBEW = 'G';
-C             LDEW >= 1,         if JOBEW = 'I'.
-C
-C     BW      (input/output) DOUBLE PRECISION array,
-C             dimension (LDBW,MBW), where MBW = MW, if JOB = 'W', and
-C             MBW = M, if JOB = 'C'.
-C             On entry, the leading NW-by-MBW part of this array must
-C             contain the input matrix BW of the system with the
-C             transfer-function matrix W.
-C             On exit, if INFO = 0, the leading NW-by-MBW part of this
-C             array contains Q'*BW, where Q is the orthogonal matrix
-C             that reduces AW to the real Schur form or the left
-C             orthogonal matrix used to reduce the pair (AW,EW),
-C             (AW',EW') or (EW',AW') to the generalized real Schur form.
-C
-C     LDBW    INTEGER
-C             The leading dimension of the array BW.  LDBW >= MAX(1,NW).
-C
-C     CW      (input/output) DOUBLE PRECISION array, dimension (LDCW,NW)
-C             On entry, the leading PCW-by-NW part of this array must
-C             contain the output matrix CW of the system with the
-C             transfer-function matrix W, where PCW = M if JOB = 'W' or
-C             PCW = MW if JOB = 'C'.
-C             On exit, if INFO = 0, the leading PCW-by-NW part of this
-C             array contains CW*Q, where Q is the orthogonal matrix that
-C             reduces AW to the real Schur form, or CW*Z, where Z is the
-C             right orthogonal matrix used to reduce the pair (AW,EW),
-C             (AW',EW') or (EW',AW') to the generalized real Schur form.
-C
-C     LDCW    INTEGER
-C             The leading dimension of the array CW.
-C             LDCW >= MAX(1,PCW), where PCW = M if JOB = 'W', or
-C             PCW = MW if JOB = 'C'.
-C
-C     DW      (input) DOUBLE PRECISION array,
-C             dimension (LDDW,MBW), where MBW = MW if JOB = 'W', and
-C             MBW = M if JOB = 'C'.
-C             The leading PCW-by-MBW part of this array must contain
-C             the feedthrough matrix DW of the system with the
-C             transfer-function matrix W, where PCW = M if JOB = 'W',
-C             or PCW = MW if JOB = 'C'.
-C
-C     LDDW    INTEGER
-C             LDDW >= MAX(1,PCW), where PCW = M if JOB = 'W', or
-C             PCW = MW if JOB = 'C'.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK =   0,    if JOBEW = 'I';
-C             LIWORK = NW+N+6, if JOBEW = 'G'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= LW1, if JOBEW = 'I',
-C             LDWORK >= LW2, if JOBEW = 'G', where
-C               LW1 = MAX( 1, NW*(NW+5), NW*N + MAX( a, N*MW, P*MW ) )
-C                     a = 0,    if DICO = 'C' or  JOB = 'W',
-C                     a = 2*NW, if DICO = 'D' and JOB = 'C';
-C               LW2 = MAX( 2*NW*NW + MAX( 11*NW+16, NW*M, MW*NW ),
-C                          NW*N + MAX( NW*N+N*N, MW*N, P*MW ) ).
-C             For good 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:  the reduction of the pair (AW,EW) to the real
-C                    generalized Schur form failed (JOBEW = 'G'),
-C                    or the reduction of the matrix AW to the real
-C                    Schur form failed (JOBEW = 'I);
-C             =  2:  the solution of the Sylvester equation failed
-C                    because the matrix A and the pencil AW-lambda*EW
-C                    have common eigenvalues (if JOB = 'W'), or the
-C                    pencil -AW-lambda*EW and A have common eigenvalues
-C                    (if JOB = 'C' and DICO = 'C'), or the pencil
-C                    AW-lambda*EW has an eigenvalue which is the
-C                    reciprocal of one of eigenvalues of A
-C                    (if JOB = 'C' and DICO = 'D');
-C             =  3:  the solution of the Sylvester equation failed
-C                    because the matrices A and AW have common
-C                    eigenvalues (if JOB = 'W'), or the matrices A
-C                    and -AW have common eigenvalues (if JOB = 'C' and
-C                    DICO = 'C'), or the matrix A has an eigenvalue
-C                    which is the reciprocal of one of eigenvalues of AW
-C                    (if JOB = 'C' and DICO = 'D');
-C             =  4:  JOB = 'W' and the pair (AW,EW) has not completely
-C                    unstable generalized eigenvalues, or JOB = 'C' and
-C                    the pair (AW,EW) has not completely stable
-C                    generalized eigenvalues.
-C
-C     METHOD
-C
-C     If JOB = 'W', the matrices of the stable projection of G*W are
-C     computed as
-C
-C       BS = B*DW + Y*BW,  CS = C,  DS = D*DW,
-C
-C     where Y satisfies the generalized Sylvester equation
-C
-C       -A*Y*EW + Y*AW + B*CW = 0.
-C
-C     If JOB = 'C', the matrices of the stable projection of G*conj(W)
-C     are computed using the following formulas:
-C
-C     - for a continuous-time system, the matrices BS, CS and DS of
-C       the stable projection are computed as
-C
-C         BS = B*DW' + Y*CW',  CS = C,  DS = D*DW',
-C
-C       where Y satisfies the generalized Sylvester equation
-C
-C         A*Y*EW' + Y*AW' + B*BW' = 0.
-C
-C     - for a discrete-time system, the matrices BS, CS and DS of
-C       the stable projection are computed as
-C
-C         BS = B*DW' + A*Y*CW',  CS = C,  DS = D*DW' + C*Y*CW',
-C
-C       where Y satisfies the generalized Sylvester equation
-C
-C         Y*EW' - A*Y*AW' = B*BW'.
-C
-C     REFERENCES
-C
-C     [1] Varga, A.
-C         Efficient and numerically reliable implementation of the
-C         frequency-weighted Hankel-norm approximation model reduction
-C         approach.
-C         Proc. 2001 ECC, Porto, Portugal, 2001.
-C
-C     [2] Zhou, K.
-C         Frequency-weighted H-infinity norm and optimal Hankel norm
-C         model reduction.
-C         IEEE Trans. Autom. Control, vol. 40, pp. 1687-1699, 1995.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on numerically stable algorithms.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, July 2000.
-C     D. Sima, University of Bucharest, March 2001.
-C     V. Sima, Research Institute for Informatics, Bucharest, Mar. 2001.
-C
-C     REVISIONS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, May 2001.
-C     V. Sima, Research Institute for Informatics, Bucharest, June 2001.
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, Nov. 2003.
-C
-C     KEYWORDS
-C
-C     Frequency weighting, model reduction, multivariable system,
-C     state-space model, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, JOB, JOBEW, STBCHK
-      INTEGER           INFO, LDA, LDAW, LDB, LDBW, LDC, LDCW,
-     $                  LDD, LDDW, LDEW, LDWORK, M, MW, N, NW, P
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), AW(LDAW,*), B(LDB,*), BW(LDBW,*),
-     $                  C(LDC,*), CW(LDCW,*), D(LDD,*), DW(LDDW,*),
-     $                  DWORK(*), EW(LDEW,*)
-C     .. Local Scalars ..
-      CHARACTER*1       EVTYPE, STDOM
-      LOGICAL           CONJS, DISCR, STABCK, UNITEW
-      DOUBLE PRECISION  ALPHA, DIF, SCALE, TOLINF, WORK
-      INTEGER           I, IA, IERR, KAI, KAR, KB, KC, KE, KF, KQ, KW,
-     $                  KZ, LDW, LDWM, LDWN, LDWP, LW, SDIM
-C     .. Local Arrays ..
-      LOGICAL           BWORK(1)
-C     .. External Functions ..
-      LOGICAL           DELCTG, LSAME
-      DOUBLE PRECISION  DLAMCH, DLANGE
-      EXTERNAL          DELCTG, DLAMCH, DLANGE, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB09JX, DGEMM, DGGES, DLACPY, DLASET, DSWAP,
-     $                  DTGSYL, DTRSYL, SB04PY, TB01WD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, MAX, SQRT
-C
-C     .. Executable Statements ..
-C
-      CONJS  = LSAME( JOB,    'C' )
-      DISCR  = LSAME( DICO,   'D' )
-      UNITEW = LSAME( JOBEW,  'I' )
-      STABCK = LSAME( STBCHK, 'C' )
-C
-      INFO = 0
-      IF( UNITEW ) THEN
-         IF ( DISCR .AND. CONJS ) THEN
-            IA = 2*NW
-         ELSE
-            IA = 0
-         END IF
-         LW = MAX( 1, NW*( NW + 5 ), NW*N + MAX( IA, N*MW, P*MW ) )
-      ELSE
-         LW = MAX( 2*NW*NW + MAX( 11*NW+16, NW*M, MW*NW ),
-     $             NW*N + MAX( NW*N + N*N, MW*N, P*MW ) )
-      END IF
-C
-C     Test the input scalar arguments.
-C
-      LDW  = MAX( 1, NW )
-      LDWM = MAX( 1, MW )
-      LDWN = MAX( 1, N )
-      LDWP = MAX( 1, P )
-      IF( .NOT. ( LSAME( JOB, 'W' ) .OR. CONJS ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( LSAME( DICO,   'C' ) .OR. DISCR  ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( LSAME( JOBEW,  'G' ) .OR. UNITEW ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT. ( LSAME( STBCHK, 'N' ) .OR. STABCK ) ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( NW.LT.0 ) THEN
-         INFO = -8
-      ELSE IF( MW.LT.0 ) THEN
-         INFO = -9
-      ELSE IF( LDA.LT.LDWN ) THEN
-         INFO = -11
-      ELSE IF( LDB.LT.LDWN ) THEN
-         INFO = -13
-      ELSE IF( LDC.LT.LDWP ) THEN
-         INFO = -15
-      ELSE IF( LDD.LT.LDWP ) THEN
-         INFO = -17
-      ELSE IF( LDAW.LT.LDW ) THEN
-         INFO = -19
-      ELSE IF( LDEW.LT.1 .OR. ( .NOT.UNITEW .AND. LDEW.LT.NW ) ) THEN
-         INFO = -21
-      ELSE IF( LDBW.LT.LDW ) THEN
-         INFO = -23
-      ELSE IF( ( .NOT.CONJS .AND. LDCW.LT.MAX( 1, M  ) ) .OR.
-     $         (      CONJS .AND. LDCW.LT.LDWM ) ) THEN
-         INFO = -25
-      ELSE IF( ( .NOT.CONJS .AND. LDDW.LT.MAX( 1, M  ) ) .OR.
-     $         (      CONJS .AND. LDDW.LT.LDWM ) ) THEN
-         INFO = -27
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -30
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09JW', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( M.EQ.0 ) THEN
-         CALL DLASET( 'Full', N, MW, ZERO, ZERO, B, LDB )
-         CALL DLASET( 'Full', P, MW, ZERO, ZERO, D, LDD )
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Set options for stability/antistability checking.
-C
-      IF( DISCR ) THEN
-         ALPHA = ONE
-      ELSE
-         ALPHA = ZERO
-      END IF
-C
-      WORK   = ONE
-      TOLINF = DLAMCH( 'Epsilon' )
-C
-      IF( UNITEW ) THEN
-C
-C        EW is the identity matrix.
-C
-         IF( NW.GT.0 ) THEN
-C
-C           Reduce AW to the real Schur form using an orthogonal
-C           similarity transformation AW <- Q'*AW*Q and apply the
-C           transformation to BW and CW: BW <- Q'*BW and CW <- CW*Q.
-C
-C           Workspace needed:  NW*(NW+5);
-C                              prefer larger.
-C
-            KW = NW*( NW + 2 ) + 1
-            IF( CONJS ) THEN
-               STDOM = 'S'
-               ALPHA = ALPHA + SQRT( TOLINF )
-               CALL TB01WD( NW, M, MW, AW, LDAW, BW, LDBW, CW, LDCW,
-     $                      DWORK(2*NW+1), NW, DWORK, DWORK(NW+1),
-     $                      DWORK(KW), LDWORK-KW+1, IERR )
-            ELSE
-               STDOM = 'U'
-               ALPHA = ALPHA - SQRT( TOLINF )
-               CALL TB01WD( NW, MW, M, AW, LDAW, BW, LDBW, CW, LDCW,
-     $                      DWORK(2*NW+1), NW, DWORK, DWORK(NW+1),
-     $                      DWORK(KW), LDWORK-KW+1, IERR )
-            END IF
-            IF( IERR.NE.0 ) THEN
-               INFO = 1
-               RETURN
-            END IF
-            IF( STABCK ) THEN
-C
-C              Check stability/antistability of eigenvalues of AV.
-C
-               CALL AB09JX( DICO, STDOM, 'S', NW, ALPHA, DWORK,
-     $                      DWORK(NW+1), DWORK, TOLINF, IERR )
-               IF( IERR.NE.0 ) THEN
-                  INFO = 4
-                  RETURN
-               END IF
-            END IF
-C
-            WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-C
-         END IF
-C
-        KW = NW*N + 1
-         IF( CONJS ) THEN
-C
-C           Compute the projection of G*conj(W).
-C
-C           Total workspace needed:  NW*N + MAX( a, N*MW, P*MW ), where
-C                                    a = 0,    if DICO = 'C',
-C                                    a = 2*NW, if DICO = 'D'.
-C
-C           Compute -BW*B'.
-C           Workspace needed: NW*N.
-C
-            CALL DGEMM( 'N', 'T', NW, N, M, -ONE, BW, LDBW, B, LDB,
-     $                  ZERO, DWORK, LDW )
-C
-            IF( DISCR ) THEN
-C
-C              Compute Y' and SCALE satisfying
-C
-C              AW*Y'*A' - Y' = -SCALE*BW*B'.
-C
-C              Additional workspace needed: 2*NW.
-C
-               CALL SB04PY( 'N', 'T', -1, NW, N, AW, LDAW, A, LDA,
-     $                      DWORK, LDW, SCALE, DWORK(KW), IERR )
-               IF( IERR.NE.0 ) THEN
-                  INFO = 3
-                  RETURN
-               END IF
-C
-C              Construct BS = B*DW' + A*Y*CW'/SCALE,
-C                        DS = D*DW' + C*Y*CW'/SCALE.
-C
-C              Additional workspace needed: MAX( N*MW, P*MW ).
-C
-C              B <- B*DW'.
-C
-               CALL DGEMM( 'N', 'T', N, MW, M, ONE, B, LDB, DW, LDDW,
-     $                     ZERO, DWORK(KW), LDWN )
-               CALL DLACPY( 'Full', N, MW, DWORK(KW), LDWN, B, LDB )
-C
-C              D <- D*DW'.
-C
-               CALL DGEMM( 'N', 'T', P, MW, M, ONE, D, LDD, DW, LDDW,
-     $                     ZERO, DWORK(KW), LDWP )
-               CALL DLACPY( 'Full', P, MW, DWORK(KW), LDWP, D, LDD )
-C
-C              B <- B + A*Y*CW'/SCALE.
-C
-               CALL DGEMM( 'T', 'T', N, MW, NW, ONE / SCALE, DWORK, LDW,
-     $                     CW, LDCW, ZERO, DWORK(KW), LDWN )
-               CALL DGEMM( 'N', 'N', N, MW, N, ONE, A, LDA,
-     $                     DWORK(KW), LDWN, ONE, B, LDB )
-C
-C              D <- D + C*Y*CW'/SCALE.
-C
-               CALL DGEMM( 'N', 'N', P, MW, N, ONE, C, LDC,
-     $                     DWORK(KW), LDWN, ONE, D, LDD )
-            ELSE
-C
-C              Compute Y' and SCALE satisfying
-C
-C              AW*Y' + Y'*A' + SCALE*BW*B' = 0.
-C
-               IF( N.GT.0 ) THEN
-                  CALL DTRSYL( 'N', 'T', 1, NW, N, AW, LDAW, A, LDA,
-     $                         DWORK, LDW, SCALE, IERR )
-                  IF( IERR.NE.0 ) THEN
-                     INFO = 3
-                     RETURN
-                  END IF
-               END IF
-C
-C              Construct BS = B*DW' + Y*CW'/SCALE,
-C                        DS = D*DW'.
-C
-C              Additional workspace needed: MAX( N*MW, P*MW ).
-C
-C              Construct B <- B*DW' + Y*CW'/SCALE.
-C
-               CALL DGEMM( 'N', 'T', N, MW, M, ONE, B, LDB, DW, LDDW,
-     $                     ZERO, DWORK(KW), LDWN )
-               CALL DLACPY( 'Full', N, MW, DWORK(KW), LDWN, B, LDB )
-               CALL DGEMM( 'T', 'T', N, MW, NW, ONE / SCALE, DWORK, LDW,
-     $                     CW, LDCW, ONE, B, LDB)
-C
-C              D <- D*DW'.
-C
-               CALL DGEMM( 'N', 'T', P, MW, M, ONE, D, LDD, DW, LDDW,
-     $                     ZERO, DWORK(KW), LDWP )
-               CALL DLACPY( 'Full', P, MW, DWORK(KW), LDWP, D, LDD )
-            END IF
-         ELSE
-C
-C           Compute the projection of G*W.
-C
-C           Total workspace needed:  NW*N + MAX( N*MW, P*MW ).
-C
-C           Compute B*CW.
-C           Workspace needed: N*NW.
-C
-            CALL DGEMM( 'N', 'N', N, NW, M, ONE, B, LDB, CW, LDCW,
-     $                  ZERO, DWORK, LDWN )
-C
-C           Compute Y and SCALE satisfying
-C
-C           A*Y - Y*AW - SCALE*B*CW = 0.
-C
-            IF( N.GT.0 ) THEN
-               CALL DTRSYL( 'N', 'N', -1, N, NW, A, LDA, AW, LDAW,
-     $                      DWORK, LDWN, SCALE, IERR )
-               IF( IERR.NE.0 ) THEN
-                  INFO = 3
-                  RETURN
-               END IF
-            END IF
-C
-C           Construct BS = B*DW + Y*BW/SCALE,
-C                     DS = D*DW.
-C
-C           Additional workspace needed: MAX( N*MW, P*MW ).
-C           Construct B <- B*DW + Y*BW/SCALE.
-C
-            CALL DGEMM( 'N', 'N', N, MW, M, ONE, B, LDB, DW, LDDW,
-     $                  ZERO, DWORK(KW), LDWN )
-            CALL DLACPY( 'Full', N, MW, DWORK(KW), LDWN, B, LDB )
-            CALL DGEMM( 'N', 'N', N, MW, NW, ONE / SCALE, DWORK, LDWN,
-     $                  BW, LDBW, ONE, B, LDB)
-C
-C           D <- D*DW.
-C
-            CALL DGEMM( 'N', 'N', P, MW, M, ONE, D, LDD, DW, LDDW,
-     $                  ZERO, DWORK(KW), LDWP )
-            CALL DLACPY( 'Full', P, MW, DWORK(KW), LDWP, D, LDD )
-         END IF
-      ELSE
-C
-C        EW is a general matrix.
-C
-         IF( NW.GT.0 ) THEN
-            TOLINF = TOLINF * DLANGE( '1', NW, NW, EW, LDEW, DWORK )
-C
-C           Reduce (AW,EW), or (AW',EW') or (EW',AW') to a generalized
-C           real Schur form using an orthogonal equivalence
-C           transformation and apply the orthogonal transformation
-C           appropriately to BW and CW, or CW' and BW'.
-C
-C           Workspace needed:  2*NW*NW + MAX( 11*NW+16, NW*M, MW*NW );
-C                              prefer larger.
-C
-            KQ = 1
-            KZ  = KQ  + NW*NW
-            KAR = KZ  + NW*NW
-            KAI = KAR + NW
-            KB  = KAI + NW
-            KW  = KB  + NW
-C
-            IF( CONJS ) THEN
-               STDOM = 'S'
-               ALPHA = ALPHA + SQRT( TOLINF )
-C
-C              Transpose AW and EW, if non-scalar.
-C
-               DO 10 I = 1, NW - 1
-                  CALL DSWAP( NW-I, AW(I+1,I), 1, AW(I,I+1), LDAW )
-                  CALL DSWAP( NW-I, EW(I+1,I), 1, EW(I,I+1), LDEW )
-   10          CONTINUE
-C
-               IF( DISCR ) THEN
-C
-C                 Reduce (EW',AW') to a generalized real Schur form
-C                 using orthogonal transformation matrices Q and Z
-C                 such that Q'*EW'*Z results in a quasi-triangular form
-C                 and Q'*AW'*Z results upper triangular.
-C                 Total workspace needed: 2*NW*NW + 11*NW + 16.
-C
-                  EVTYPE = 'R'
-                  CALL DGGES( 'Vectors', 'Vectors', 'Not ordered',
-     $                        DELCTG, NW, EW, LDEW, AW, LDAW, SDIM,
-     $                        DWORK(KAR), DWORK(KAI), DWORK(KB),
-     $                        DWORK(KQ), LDW, DWORK(KZ), LDW,
-     $                        DWORK(KW), LDWORK-KW+1, BWORK, IERR )
-               ELSE
-C
-C                 Reduce (AW',EW') to a generalized real Schur form
-C                 using orthogonal transformation matrices Q and Z
-C                 such that Q'*AW'*Z results in a quasi-triangular form
-C                 and Q'*EW'*Z results upper triangular.
-C                 Total workspace needed: 2*NW*NW + 11*NW + 16.
-C
-                  EVTYPE = 'G'
-                  CALL DGGES( 'Vectors', 'Vectors', 'Not ordered',
-     $                        DELCTG, NW, AW, LDAW, EW, LDEW, SDIM,
-     $                        DWORK(KAR), DWORK(KAI), DWORK(KB),
-     $                        DWORK(KQ), LDW, DWORK(KZ), LDW,
-     $                        DWORK(KW), LDWORK-KW+1, BWORK, IERR )
-               END IF
-               IF( IERR.NE.0 ) THEN
-                  INFO = 1
-                  RETURN
-               END IF
-               IF( STABCK ) THEN
-C
-C                 Check stability/antistability of generalized
-C                 eigenvalues of the pair (AV,EV).
-C
-                  CALL AB09JX( DICO, STDOM, EVTYPE, NW, ALPHA,
-     $                         DWORK(KAR), DWORK(KAI), DWORK(KB),
-     $                         TOLINF, IERR )
-                  IF( IERR.NE.0 ) THEN
-                     INFO = 4
-                     RETURN
-                  END IF
-               END IF
-               WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-C
-C              Compute Z'*BW and CW*Q.
-C              Total workspace needed: 2*NW*NW + NW*MAX(M,MW).
-C
-               KW = KAR
-               CALL DLACPY( 'Full', NW, M, BW, LDBW, DWORK(KW), LDW )
-               CALL DGEMM( 'T', 'N', NW, M, NW, ONE, DWORK(KZ), LDW,
-     $                     DWORK(KW), LDW, ZERO, BW, LDBW )
-               CALL DLACPY( 'Full', MW, NW, CW, LDCW, DWORK(KW), LDWM )
-               CALL DGEMM( 'N', 'N', MW, NW, NW, ONE, DWORK(KW), LDWM,
-     $                     DWORK(KQ), LDW, ZERO, CW, LDCW )
-            ELSE
-C
-C              Reduce (AW,EW) to a generalized real Schur form
-C              using orthogonal transformation matrices Q and Z
-C              such that Q'*AW*Z results in a quasi-triangular form
-C              and Q'*EW*Z results upper triangular.
-C              Total workspace needed: 2*NW*NW + 11*NW + 16.
-C
-               STDOM  = 'U'
-               EVTYPE = 'G'
-               ALPHA  = ALPHA - SQRT( TOLINF )
-               CALL DGGES( 'Vectors', 'Vectors', 'Not ordered',
-     $                     DELCTG, NW, AW, LDAW, EW, LDEW, SDIM,
-     $                     DWORK(KAR), DWORK(KAI), DWORK(KB),
-     $                     DWORK(KQ), LDW, DWORK(KZ), LDW,
-     $                     DWORK(KW), LDWORK-KW+1, BWORK, IERR )
-               IF( IERR.NE.0 ) THEN
-                  INFO = 1
-                  RETURN
-               END IF
-               IF( STABCK ) THEN
-C
-C                 Check stability/antistability of generalized
-C                 eigenvalues of the pair (AV,EV).
-C
-                  CALL AB09JX( DICO, STDOM, EVTYPE, NW, ALPHA,
-     $                         DWORK(KAR), DWORK(KAI), DWORK(KB),
-     $                         TOLINF, IERR )
-                  IF( IERR.NE.0 ) THEN
-                     INFO = 4
-                     RETURN
-                  END IF
-               END IF
-               WORK = MAX( WORK, DWORK(KW) + DBLE( KW - 1 ) )
-C
-C              Compute Q'*BW and CW*Z.
-C              Total workspace needed: 2*NW*NW + NW*MAX(M,MW).
-C
-               KW = KAR
-               CALL DLACPY( 'Full', NW, MW, BW, LDBW, DWORK(KW), LDW )
-               CALL DGEMM( 'T', 'N', NW, MW, NW, ONE, DWORK(KQ), LDW,
-     $                     DWORK(KW), LDW, ZERO, BW, LDBW )
-               CALL DLACPY( 'Full', M, NW, CW, LDCW, DWORK(KW), M )
-               CALL DGEMM( 'N', 'N', M, NW, NW, ONE, DWORK(KW), M,
-     $                     DWORK(KZ), LDW, ZERO, CW, LDCW )
-            END IF
-            WORK = MAX( WORK, DBLE( 2*NW*NW + NW*MAX( M, MW ) ) )
-C
-         END IF
-C
-         KC = 1
-         KF = KC + NW*N
-         KE = KF + NW*N
-         KW = KE + N*N
-         CALL DLASET( 'Full', N, NW, ZERO, ZERO, DWORK(KF), LDWN )
-C
-         IF( CONJS ) THEN
-C
-C           Compute the projection of G*conj(W).
-C
-C           Total workspace needed: NW*N + MAX( NW*N+N*N, MW*N, P*MW )
-C
-C           Compute B*BW'.
-C           Workspace needed: N*NW.
-C
-            CALL DGEMM( 'N', 'T', N, NW, M, ONE, B, LDB, BW, LDBW,
-     $                  ZERO, DWORK(KC), LDWN )
-C
-            IF( DISCR ) THEN
-C
-C              Compute Y and SCALE satisfying
-C
-C              Y*EW' - A*Y*AW' = SCALE*B*BW' by solving equivalently
-C
-C              A*X - Y*EW' = -SCALE*B*BW',
-C              X   - Y*AW' = 0.
-C
-C              Additional workspace needed:
-C              real    N*NW + N*N;
-C              integer NW+N+6.
-C
-C
-               IF( N.GT.0 ) THEN
-                  CALL DLASET( 'Full', N, N, ZERO, ONE, DWORK(KE), LDWN
-     $                       )
-                  CALL DTGSYL( 'N', 0, N, NW, A, LDA, EW, LDEW,
-     $                         DWORK(KC), LDWN, DWORK(KE), LDWN, AW,
-     $                         LDAW, DWORK(KF), LDWN, SCALE, DIF,
-     $                         DWORK(KW), LDWORK-KW+1, IWORK, IERR )
-C
-C                 Note that the computed solution in DWORK(KC) is -Y.
-C
-                  IF( IERR.NE.0 ) THEN
-                     INFO = 2
-                     RETURN
-                  END IF
-               END IF
-C
-C              Construct BS = B*DW' + A*Y*CW'/SCALE,
-C                        DS = D*DW' + C*Y*CW'/SCALE.
-C
-C              Additional workspace needed: MAX( N*MW, P*MW ).
-C
-C              B <- B*DW'.
-C
-               CALL DGEMM( 'N', 'T', N, MW, M, ONE, B, LDB, DW, LDDW,
-     $                     ZERO, DWORK(KW), LDWN )
-               CALL DLACPY( 'Full', N, MW, DWORK(KW), LDWN, B, LDB )
-C
-C              D <- D*DW'.
-C
-               CALL DGEMM( 'N', 'T', P, MW, M, ONE, D, LDD, DW, LDDW,
-     $                     ZERO, DWORK(KW), LDWP )
-               CALL DLACPY( 'Full', P, MW, DWORK(KW), LDWP, D, LDD )
-C
-C              B <- B + A*Y*CW'/SCALE.
-C
-               CALL DGEMM( 'N', 'T', N, MW, NW, -ONE / SCALE,
-     $                     DWORK(KF), LDWN, CW, LDCW, ZERO,
-     $                     DWORK(KW), LDWN )
-               CALL DGEMM( 'N', 'N', N, MW, N, ONE, A, LDA,
-     $                     DWORK(KW), LDWN, ONE, B, LDB )
-C
-C              D <- D + C*Y*CW'/SCALE.
-C
-               CALL DGEMM( 'N', 'N', P, MW, N, ONE, C, LDC,
-     $                     DWORK(KW), LDWN, ONE, D, LDD )
-            ELSE
-C
-C              Compute Y and SCALE satisfying
-C
-C              A*Y*EW' + Y*AW' + SCALE*B*BW' = 0 by solving equivalently
-C
-C              A*X    - Y*AW' = SCALE*B*BW',
-C              (-I)*X - Y*EW' = 0.
-C
-C              Additional workspace needed:
-C              real    N*NW+N*N;
-C              integer NW+N+6.
-C
-               IF( N.GT.0 ) THEN
-                  CALL DLASET( 'Full', N, N, ZERO, -ONE, DWORK(KE), LDWN
-     $                       )
-                  CALL DTGSYL( 'N', 0, N, NW, A, LDA, AW, LDAW,
-     $                         DWORK(KC), LDWN, DWORK(KE), LDWN, EW,
-     $                         LDEW, DWORK(KF), LDWN, SCALE, DIF,
-     $                         DWORK(KW), LDWORK-KW+1, IWORK, IERR )
-                  IF( IERR.NE.0 ) THEN
-                     INFO = 2
-                     RETURN
-                  END IF
-               END IF
-C
-C              Construct BS = B*DW' + Y*CW'/SCALE,
-C                        DS = D*DW'.
-C
-C              Additional workspace needed: MAX( N*MW, P*MW ).
-C
-C              Construct B <- B*DW' + Y*CW'/SCALE.
-C
-               CALL DGEMM( 'N', 'T', N, MW, M, ONE, B, LDB, DW, LDDW,
-     $                     ZERO, DWORK(KW), LDWN )
-               CALL DLACPY( 'Full', N, MW, DWORK(KW), LDWN, B, LDB )
-               CALL DGEMM( 'N', 'T', N, MW, NW, ONE / SCALE,
-     $                     DWORK(KF), LDWN, CW, LDCW, ONE, B, LDB )
-C
-C              D <- D*DW'.
-C
-               CALL DGEMM( 'N', 'T', P, MW, M, ONE, D, LDD, DW, LDDW,
-     $                     ZERO, DWORK(KW), LDWP )
-               CALL DLACPY( 'Full', P, MW, DWORK(KW), LDWP, D, LDD )
-            END IF
-         ELSE
-C
-C           Compute the projection of G*W.
-C
-C           Total workspace needed: NW*N + MAX( NW*N+N*N, MW*N, P*MW )
-C
-C           Compute B*CW.
-C           Workspace needed: N*NW.
-C
-            CALL DGEMM( 'N', 'N', N, NW, M, ONE, B, LDB, CW, LDCW,
-     $                  ZERO, DWORK(KC), LDWN )
-C
-C           Compute Y and SCALE satisfying
-C
-C           -A*Y*EW + Y*AW + B*CW = 0 by solving equivalently
-C
-C           A*X - Y*AW = SCALE*B*CW,
-C           X   - Y*EW = 0.
-C
-C           Additional workspace needed:
-C           real    N*NW + N*N;
-C           integer NW+N+6.
-C
-            IF( N.GT.0 ) THEN
-               CALL DLASET( 'Full', N, N, ZERO, ONE, DWORK(KE), LDWN )
-               CALL DTGSYL( 'N', 0, N, NW, A, LDA, AW, LDAW,
-     $                      DWORK(KC), LDWN, DWORK(KE), LDWN, EW, LDEW,
-     $                      DWORK(KF), LDWN, SCALE, DIF, DWORK(KW),
-     $                      LDWORK-KW+1, IWORK, IERR )
-               IF( IERR.NE.0 ) THEN
-                  INFO = 2
-                  RETURN
-               END IF
-            END IF
-C
-C           Construct BS = B*DW + Y*BW/SCALE,
-C                     DS = D*DW.
-C
-C           Additional workspace needed: MAX( N*MW, P*MW ).
-C           Construct B <- B*DW + Y*BW/SCALE.
-C
-            CALL DGEMM( 'N', 'N', N, MW, M, ONE, B, LDB, DW, LDDW,
-     $                  ZERO, DWORK(KW), LDWN )
-            CALL DLACPY( 'Full', N, MW, DWORK(KW), LDWN, B, LDB )
-            CALL DGEMM( 'N', 'N', N, MW, NW, ONE / SCALE,
-     $                  DWORK(KF), LDWN, BW, LDBW, ONE, B, LDB)
-C
-C           D <- D*DW.
-C
-            CALL DGEMM( 'N', 'N', P, MW, M, ONE, D, LDD, DW, LDDW,
-     $                  ZERO, DWORK(KW), LDWP )
-            CALL DLACPY( 'Full', P, MW, DWORK(KW), LDWP, D, LDD )
-         END IF
-      END IF
-C
-      DWORK(1) = MAX( WORK, DBLE( LW ) )
-C
-      RETURN
-C *** Last line of AB09JW ***
-      END
--- a/extra/control-devel/src/AB09JX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,253 +0,0 @@
-      SUBROUTINE AB09JX( DICO, STDOM, EVTYPE, N, ALPHA, ER, EI, ED,
-     $                   TOLINF, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To check stability/antistability of finite eigenvalues with
-C     respect to a given stability domain.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the stability domain as follows:
-C             = 'C':  for a continuous-time system;
-C             = 'D':  for a discrete-time system.
-C
-C     STDOM   CHARACTER*1
-C             Specifies whether the domain of interest is of stability
-C             type (left part of complex plane or inside of a circle)
-C             or of instability type (right part of complex plane or
-C             outside of a circle) as follows:
-C             = 'S':  stability type domain;
-C             = 'U':  instability type domain.
-C
-C     EVTYPE  CHARACTER*1
-C             Specifies whether the eigenvalues arise from a standard
-C             or a generalized eigenvalue problem as follows:
-C             = 'S':  standard eigenvalue problem;
-C             = 'G':  generalized eigenvalue problem;
-C             = 'R':  reciprocal generalized eigenvalue problem.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The dimension of vectors ER, EI and ED.  N >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             Specifies the boundary of the domain of interest for the
-C             eigenvalues. For a continuous-time system
-C             (DICO = 'C'), ALPHA is the boundary value for the real
-C             parts of eigenvalues, while for a discrete-time system
-C             (DICO = 'D'), ALPHA >= 0 represents the boundary value for
-C             the moduli of eigenvalues.
-C
-C     ER, EI, (input) DOUBLE PRECISION arrays, dimension (N)
-C     ED      If EVTYPE = 'S', ER(j) + EI(j)*i, j = 1,...,N, are
-C             the eigenvalues of a real matrix.
-C             ED is not referenced and is implicitly considered as
-C             a vector having all elements equal to one.
-C             If EVTYPE = 'G' or EVTYPE = 'R', (ER(j) + EI(j)*i)/ED(j),
-C             j = 1,...,N, are the generalized eigenvalues of a pair of
-C             real matrices. If ED(j) is zero, then the j-th generalized
-C             eigenvalue is infinite.
-C             Complex conjugate pairs of eigenvalues must appear
-C             consecutively.
-C
-C     Tolerances
-C
-C     TOLINF  DOUBLE PRECISION
-C             If EVTYPE = 'G' or 'R', TOLINF contains the tolerance for
-C             detecting infinite generalized eigenvalues.
-C             0 <= TOLINF < 1.
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             =  0:  successful exit, i.e., all eigenvalues lie within
-C                    the domain of interest defined by DICO, STDOM
-C                    and ALPHA;
-C             <  0:  if INFO = -i, the i-th argument had an illegal
-C                    value;
-C             =  1:  some eigenvalues lie outside the domain of interest
-C                    defined by DICO, STDOM and ALPHA.
-C     METHOD
-C
-C     The domain of interest for an eigenvalue lambda is defined by the
-C     parameters ALPHA, DICO and STDOM as follows:
-C        - for a continuous-time system (DICO = 'C'):
-C               Real(lambda) < ALPHA if STDOM = 'S';
-C               Real(lambda) > ALPHA if STDOM = 'U';
-C        - for a discrete-time system (DICO = 'D'):
-C               Abs(lambda) < ALPHA if STDOM = 'S';
-C               Abs(lambda) > ALPHA if STDOM = 'U'.
-C     If EVTYPE = 'R', the same conditions apply for 1/lambda.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, May 2001.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, June 2001.
-C
-C     KEYWORDS
-C
-C     Stability.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION ZERO, ONE
-      PARAMETER        ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER        DICO, EVTYPE, STDOM
-      INTEGER          INFO, N
-      DOUBLE PRECISION ALPHA, TOLINF
-C     .. Array Arguments ..
-      DOUBLE PRECISION ED(*), EI(*), ER(*)
-C     .. Local Scalars
-      LOGICAL          DISCR, RECEVP, STAB, STDEVP
-      DOUBLE PRECISION ABSEV, RPEV, SCALE
-      INTEGER          I
-C     .. External Functions ..
-      LOGICAL          LSAME
-      DOUBLE PRECISION DLAPY2
-      EXTERNAL         DLAPY2, LSAME
-C     .. External Subroutines ..
-      EXTERNAL         XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC        ABS
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      DISCR  = LSAME( DICO,   'D' )
-      STAB   = LSAME( STDOM,  'S' )
-      STDEVP = LSAME( EVTYPE, 'S' )
-      RECEVP = LSAME( EVTYPE, 'R' )
-C
-C     Check the scalar input arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( STAB .OR. LSAME( STDOM, 'U' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( STDEVP .OR. LSAME( EVTYPE, 'G' ) .OR.
-     $                 RECEVP ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( DISCR .AND. ALPHA.LT.ZERO ) THEN
-         INFO = -5
-      ELSE IF( TOLINF.LT.ZERO .OR. TOLINF.GE.ONE ) THEN
-         INFO = -9
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AB09JX', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( N.EQ.0 )
-     $   RETURN
-C
-      IF( STAB ) THEN
-C
-C        Check the stability of finite eigenvalues.
-C
-         SCALE = ONE
-         IF( DISCR ) THEN
-            DO 10 I = 1, N
-               ABSEV = DLAPY2( ER(I), EI(I) )
-               IF( RECEVP ) THEN
-                  SCALE = ABSEV
-                  ABSEV = ABS( ED(I) )
-               ELSE IF( .NOT.STDEVP ) THEN
-                  SCALE = ED(I)
-               END IF
-               IF( ABS( SCALE ).GT.TOLINF .AND.
-     $            ABSEV.GE.ALPHA*SCALE ) THEN
-                  INFO = 1
-                  RETURN
-               END IF
-   10       CONTINUE
-         ELSE
-            DO 20 I = 1, N
-               RPEV = ER(I)
-               IF( RECEVP ) THEN
-                  SCALE = RPEV
-                  RPEV = ED(I)
-               ELSE IF( .NOT.STDEVP ) THEN
-                  SCALE = ED(I)
-               END IF
-               IF( ABS( SCALE ).GT.TOLINF .AND.
-     $            RPEV.GE.ALPHA*SCALE ) THEN
-                  INFO = 1
-                  RETURN
-               END IF
-   20       CONTINUE
-         END IF
-      ELSE
-C
-C        Check the anti-stability of finite eigenvalues.
-C
-         IF( DISCR ) THEN
-            DO 30 I = 1, N
-               ABSEV = DLAPY2( ER(I), EI(I) )
-               IF( RECEVP ) THEN
-                  SCALE = ABSEV
-                  ABSEV = ABS( ED(I) )
-               ELSE IF( .NOT.STDEVP ) THEN
-                  SCALE = ED(I)
-               END IF
-               IF( ABS( SCALE ).GT.TOLINF .AND.
-     $            ABSEV.LE.ALPHA*SCALE ) THEN
-                  INFO = 1
-                  RETURN
-               END IF
-   30       CONTINUE
-         ELSE
-            DO 40 I = 1, N
-               RPEV = ER(I)
-               IF( RECEVP ) THEN
-                  SCALE = RPEV
-                  RPEV = ED(I)
-               ELSE IF( .NOT.STDEVP ) THEN
-                  SCALE = ED(I)
-               END IF
-               IF( ABS( SCALE ).GT.TOLINF .AND.
-     $            RPEV.LE.ALPHA*SCALE ) THEN
-                  INFO = 1
-                  RETURN
-               END IF
-   40       CONTINUE
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of AB09JX ***
-      END
--- a/extra/control-devel/src/AG07BD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,273 +0,0 @@
-      SUBROUTINE AG07BD( JOBE, N, M, A, LDA, E, LDE, B, LDB, C, LDC,
-     $                   D, LDD, AI, LDAI, EI, LDEI, BI, LDBI, CI, LDCI,
-     $                   DI, LDDI, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the inverse (Ai-lambda*Ei,Bi,Ci,Di) of a given
-C     descriptor system (A-lambda*E,B,C,D).
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBE    CHARACTER*1
-C             Specifies whether E is a general square or an identity
-C             matrix as follows:
-C             = 'G':  E is a general square matrix;
-C             = 'I':  E is the identity matrix.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the square matrices A and E;
-C             also the number of rows of matrix B and the number of
-C             columns of matrix C.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs and outputs, i.e., the number
-C             of columns of matrices B and D and the number of rows of
-C             matrices C and D.  M >= 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             state matrix A of the original system.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= MAX(1,N).
-C
-C     E       (input) DOUBLE PRECISION array, dimension (LDE,N)
-C             If JOBE = 'G', the leading N-by-N part of this array must
-C             contain the descriptor matrix E of the original system.
-C             If JOBE = 'I', then E is assumed to be the identity
-C             matrix and is not referenced.
-C
-C     LDE     INTEGER
-C             The leading dimension of the array E.
-C             LDE >= MAX(1,N), if JOBE = 'G';
-C             LDE >= 1,        if JOBE = 'I'.
-C
-C     B       (input) DOUBLE PRECISION array, dimension (LDB,M)
-C             The leading N-by-M part of this array must contain the
-C             input matrix B of the original system.
-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 M-by-N part of this array must contain the
-C             output matrix C of the original system.
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.  LDC >= MAX(1,M).
-C
-C     D       (input) DOUBLE PRECISION array, dimension (LDD,M)
-C             The leading M-by-M part of this array must contain the
-C             feedthrough matrix D of the original system.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.  LDD >= MAX(1,M).
-C
-C     AI      (output) DOUBLE PRECISION array, dimension (LDAI,N+M)
-C             The leading (N+M)-by-(N+M) part of this array contains
-C             the state matrix Ai of the inverse system.
-C             If LDAI = LDA >= N+M, then AI and A can share the same
-C             storage locations.
-C
-C     LDAI    INTEGER
-C             The leading dimension of the array AI.
-C             LDAI >= MAX(1,N+M).
-C
-C     EI      (output) DOUBLE PRECISION array, dimension (LDEI,N+M)
-C             The leading (N+M)-by-(N+M) part of this array contains
-C             the descriptor matrix Ei of the inverse system.
-C             If LDEI = LDE >= N+M, then EI and E can share the same
-C             storage locations.
-C
-C     LDEI    INTEGER
-C             The leading dimension of the array EI.
-C             LDEI >= MAX(1,N+M).
-C
-C     BI      (output) DOUBLE PRECISION array, dimension (LDBI,M)
-C             The leading (N+M)-by-M part of this array contains
-C             the input matrix Bi of the inverse system.
-C             If LDBI = LDB >= N+M, then BI and B can share the same
-C             storage locations.
-C
-C     LDBI    INTEGER
-C             The leading dimension of the array BI.
-C             LDBI >= MAX(1,N+M).
-C
-C     CI      (output) DOUBLE PRECISION array, dimension (LDCI,N+M)
-C             The leading M-by-(N+M) part of this array contains
-C             the output matrix Ci of the inverse system.
-C             If LDCI = LDC, CI and C can share the same storage
-C             locations.
-C
-C     LDCI    INTEGER
-C             The leading dimension of the array CI.  LDCI >= MAX(1,M).
-C
-C     DI      (output) DOUBLE PRECISION array, dimension (LDDI,M)
-C             The leading M-by-M part of this array contains
-C             the feedthrough matrix Di = 0 of the inverse system.
-C             DI and D can share the same storage locations.
-C
-C     LDDI    INTEGER
-C             The leading dimension of the array DI.  LDDI >= MAX(1,M).
-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     METHOD
-C
-C     The matrices of the inverse system are computed with the formulas
-C
-C                ( E  0 )        ( A  B )         (  0 )
-C           Ei = (      ) , Ai = (      ) ,  Bi = (    ),
-C                ( 0  0 )        ( C  D )         ( -I )
-C
-C           Ci = ( 0  I ),  Di = 0.
-C
-C     FURTHER COMMENTS
-C
-C     The routine does not perform an invertibility test. This check can
-C     be performed by using the SLICOT routines AB08NX or AG08BY.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, July 2000.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Mar. 2001.
-C
-C     KEYWORDS
-C
-C     Descriptor system, inverse system, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER          JOBE
-      INTEGER            INFO, LDA, LDAI, LDB, LDBI, LDC, LDCI,
-     $                   LDD, LDDI, LDE, LDEI, M, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA,*), AI(LDAI,*), B(LDB,*), BI(LDBI,*),
-     $                   C(LDC,*), CI(LDCI,*), D(LDD,*), DI(LDDI,*),
-     $                   E(LDE,*), EI(LDEI,*)
-C     .. Local Scalars ..
-      LOGICAL            UNITE
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DLACPY, DLASET, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX
-C     .. Executable Statements ..
-C
-      INFO = 0
-C
-C     Test the input scalar arguments.
-C
-      UNITE = LSAME( JOBE, 'I' )
-      IF( .NOT. ( LSAME( JOBE, 'G' ) .OR. UNITE ) ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -5
-      ELSE IF( LDE.LT.1 .OR. ( .NOT.UNITE .AND. LDE.LT.N ) ) THEN
-         INFO = -7
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
-         INFO = -11
-      ELSE IF( LDD.LT.MAX( 1, M ) ) THEN
-         INFO = -13
-      ELSE IF( LDAI.LT.MAX( 1, N+M ) ) THEN
-         INFO = -15
-      ELSE IF( LDEI.LT.MAX( 1, N+M ) ) THEN
-         INFO = -17
-      ELSE IF( LDBI.LT.MAX( 1, N+M ) ) THEN
-         INFO = -19
-      ELSE IF( LDCI.LT.MAX( 1, M ) ) THEN
-         INFO = -21
-      ELSE IF( LDDI.LT.MAX( 1, M ) ) THEN
-         INFO = -23
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'AG07BD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( M.EQ.0 )
-     $   RETURN
-C
-C     Form Ai.
-C
-      CALL DLACPY( 'Full', N, N, A, LDA, AI, LDAI )
-      CALL DLACPY( 'Full', M, N, C, LDC, AI(N+1,1), LDAI )
-      CALL DLACPY( 'Full', N, M, B, LDB, AI(1,N+1), LDAI )
-      CALL DLACPY( 'Full', M, M, D, LDD, AI(N+1,N+1), LDAI )
-C
-C     Form Ei.
-C
-      IF( UNITE ) THEN
-         CALL DLASET( 'Full', N+M, N, ZERO, ONE, EI, LDEI )
-      ELSE
-         CALL DLACPY( 'Full', N, N, E, LDE, EI, LDEI )
-         CALL DLASET( 'Full', M, N, ZERO, ZERO, EI(N+1,1), LDEI )
-      END IF
-      CALL DLASET( 'Full', N+M, M, ZERO, ZERO, EI(1,N+1), LDEI )
-C
-C     Form Bi.
-C
-      CALL DLASET( 'Full', N, M, ZERO, ZERO, BI, LDBI )
-      CALL DLASET( 'Full', M, M, ZERO, -ONE, BI(N+1,1), LDBI )
-C
-C     Form Ci.
-C
-      CALL DLASET( 'Full', M, N, ZERO, ZERO, CI, LDCI )
-      CALL DLASET( 'Full', M, M, ZERO, ONE, CI(1,N+1), LDCI )
-C
-C     Set Di.
-C
-      CALL DLASET( 'Full', M, M, ZERO, ZERO, DI, LDDI )
-C
-      RETURN
-C *** Last line of AG07BD ***
-      END
--- a/extra/control-devel/src/DG01MD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,235 +0,0 @@
-      SUBROUTINE DG01MD( INDI, N, XR, XI, 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 discrete Fourier transform, or inverse transform,
-C     of a complex signal.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     INDI    CHARACTER*1
-C             Indicates whether a Fourier transform or inverse Fourier
-C             transform is to be performed as follows:
-C             = 'D':  (Direct) Fourier transform;
-C             = 'I':  Inverse Fourier transform.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The number of complex samples.  N must be a power of 2.
-C             N >= 2.
-C
-C     XR      (input/output) DOUBLE PRECISION array, dimension (N)
-C             On entry, this array must contain the real part of either
-C             the complex signal z if INDI = 'D', or f(z) if INDI = 'I'.
-C             On exit, this array contains either the real part of the
-C             computed Fourier transform f(z) if INDI = 'D', or the
-C             inverse Fourier transform z of f(z) if INDI = 'I'.
-C
-C     XI      (input/output) DOUBLE PRECISION array, dimension (N)
-C             On entry, this array must contain the imaginary part of
-C             either z if INDI = 'D', or f(z) if INDI = 'I'.
-C             On exit, this array contains either the imaginary part of
-C             f(z) if INDI = 'D', or z if INDI = 'I'.
-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     METHOD
-C
-C     If INDI = 'D', then the routine performs a discrete Fourier
-C     transform on the complex signal Z(i), i = 1,2,...,N. If the result
-C     is denoted by FZ(k), k = 1,2,...,N, then the relationship between
-C     Z and FZ is given by the formula:
-C
-C                     N            ((k-1)*(i-1))
-C            FZ(k) = SUM ( Z(i) * V              ),
-C                    i=1
-C                                     2
-C     where V = exp( -2*pi*j/N ) and j  = -1.
-C
-C     If INDI = 'I', then the routine performs an inverse discrete
-C     Fourier transform on the complex signal FZ(k), k = 1,2,...,N. If
-C     the result is denoted by Z(i), i = 1,2,...,N, then the
-C     relationship between Z and FZ is given by the formula:
-C
-C                    N             ((k-1)*(i-1))
-C            Z(i) = SUM ( FZ(k) * W              ),
-C                   k=1
-C
-C     where W = exp( 2*pi*j/N ).
-C
-C     Note that a discrete Fourier transform, followed by an inverse
-C     discrete Fourier transform, will result in a signal which is a
-C     factor N larger than the original input signal.
-C
-C     REFERENCES
-C
-C     [1] Rabiner, L.R. and Rader, C.M.
-C         Digital Signal Processing.
-C         IEEE Press, 1972.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm requires 0( N*log(N) ) operations.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1997.
-C     Supersedes Release 2.0 routine DG01AD by R. Dekeyser, State
-C     University of Gent, Belgium.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Complex signals, digital signal processing, fast Fourier
-C     transform.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, HALF, ONE, TWO, EIGHT
-      PARAMETER         ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0,
-     $                    TWO = 2.0D0, EIGHT = 8.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         INDI
-      INTEGER           INFO, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION  XI(*), XR(*)
-C     .. Local Scalars ..
-      LOGICAL           LINDI
-      INTEGER           I, J, K, L, M
-      DOUBLE PRECISION  PI2, TI, TR, WHELP, WI, WR, WSTPI, WSTPR
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         ATAN, DBLE, MOD, SIN
-C     .. Executable Statements ..
-C
-      INFO = 0
-      LINDI = LSAME( INDI, 'D' )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.LINDI .AND. .NOT.LSAME( INDI, 'I' ) ) THEN
-         INFO = -1
-      ELSE
-         J = 0
-         IF( N.GE.2 ) THEN
-            J = N
-C           WHILE ( MOD( J, 2 ).EQ.0 ) DO
-   10       CONTINUE
-            IF ( MOD( J, 2 ).EQ.0 ) THEN
-               J = J/2
-               GO TO 10
-            END IF
-C           END WHILE 10
-         END IF
-         IF ( J.NE.1 ) INFO = -2
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'DG01MD', -INFO )
-         RETURN
-      END IF
-C
-C     Inplace shuffling of data.
-C
-      J = 1
-C
-      DO 30 I = 1, N
-         IF ( J.GT.I ) THEN
-            TR = XR(I)
-            TI = XI(I)
-            XR(I) = XR(J)
-            XI(I) = XI(J)
-            XR(J) = TR
-            XI(J) = TI
-         END IF
-         K = N/2
-C        REPEAT
-   20    IF ( J.GT.K ) THEN
-            J = J - K
-            K = K/2
-            IF ( K.GE.2 ) GO TO 20
-         END IF
-C        UNTIL ( K.LT.2 )
-         J = J + K
-   30 CONTINUE
-C
-C     Transform by decimation in time.
-C
-      PI2 = EIGHT*ATAN( ONE )
-      IF ( LINDI ) PI2 = -PI2
-C
-      I = 1
-C
-C     WHILE ( I.LT.N ) DO
-C
-   40 IF ( I.LT.N ) THEN
-         L = 2*I
-         WHELP = PI2/DBLE( L )
-         WSTPI = SIN( WHELP )
-         WHELP = SIN( HALF*WHELP )
-         WSTPR = -TWO*WHELP*WHELP
-         WR = ONE
-         WI = ZERO
-C
-         DO 60 J = 1, I
-C
-            DO 50 K = J, N, L
-               M = K + I
-               TR = WR*XR(M) - WI*XI(M)
-               TI = WR*XI(M) + WI*XR(M)
-               XR(M) = XR(K) - TR
-               XI(M) = XI(K) - TI
-               XR(K) = XR(K) + TR
-               XI(K) = XI(K) + TI
-   50       CONTINUE
-C
-            WHELP = WR
-            WR = WR + WR*WSTPR - WI*WSTPI
-            WI = WI + WHELP*WSTPI + WI*WSTPR
-   60    CONTINUE
-C
-         I = L
-         GO TO 40
-C        END WHILE 40
-      END IF
-C
-      RETURN
-C *** Last line of DG01MD ***
-      END
--- a/extra/control-devel/src/IB01AD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,686 +0,0 @@
-      SUBROUTINE IB01AD( METH, ALG, JOBD, BATCH, CONCT, CTRL, NOBR, M,
-     $                   L, NSMP, U, LDU, Y, LDY, N, R, LDR, SV, RCOND,
-     $                   TOL, IWORK, DWORK, LDWORK, IWARN, 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 preprocess the input-output data for estimating the matrices
-C     of a linear time-invariant dynamical system and to find an
-C     estimate of the system order. The input-output data can,
-C     optionally, be processed sequentially.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     METH    CHARACTER*1
-C             Specifies the subspace identification method to be used,
-C             as follows:
-C             = 'M':  MOESP  algorithm with past inputs and outputs;
-C             = 'N':  N4SID  algorithm.
-C
-C     ALG     CHARACTER*1
-C             Specifies the algorithm for computing the triangular
-C             factor R, as follows:
-C             = 'C':  Cholesky algorithm applied to the correlation
-C                     matrix of the input-output data;
-C             = 'F':  Fast QR algorithm;
-C             = 'Q':  QR algorithm applied to the concatenated block
-C                     Hankel matrices.
-C
-C     JOBD    CHARACTER*1
-C             Specifies whether or not the matrices B and D should later
-C             be computed using the MOESP approach, as follows:
-C             = 'M':  the matrices B and D should later be computed
-C                     using the MOESP approach;
-C             = 'N':  the matrices B and D should not be computed using
-C                     the MOESP approach.
-C             This parameter is not relevant for METH = 'N'.
-C
-C     BATCH   CHARACTER*1
-C             Specifies whether or not sequential data processing is to
-C             be used, and, for sequential processing, whether or not
-C             the current data block is the first block, an intermediate
-C             block, or the last block, as follows:
-C             = 'F':  the first block in sequential data processing;
-C             = 'I':  an intermediate block in sequential data
-C                     processing;
-C             = 'L':  the last block in sequential data processing;
-C             = 'O':  one block only (non-sequential data processing).
-C             NOTE that when  100  cycles of sequential data processing
-C                  are completed for  BATCH = 'I',  a warning is
-C                  issued, to prevent for an infinite loop.
-C
-C     CONCT   CHARACTER*1
-C             Specifies whether or not the successive data blocks in
-C             sequential data processing belong to a single experiment,
-C             as follows:
-C             = 'C':  the current data block is a continuation of the
-C                     previous data block and/or it will be continued
-C                     by the next data block;
-C             = 'N':  there is no connection between the current data
-C                     block and the previous and/or the next ones.
-C             This parameter is not used if BATCH = 'O'.
-C
-C     CTRL    CHARACTER*1
-C             Specifies whether or not the user's confirmation of the
-C             system order estimate is desired, as follows:
-C             = 'C':  user's confirmation;
-C             = 'N':  no confirmation.
-C             If  CTRL = 'C',  a reverse communication routine,  IB01OY,
-C             is indirectly called (by SLICOT Library routine IB01OD),
-C             and, after inspecting the singular values and system order
-C             estimate,  n,  the user may accept  n  or set a new value.
-C             IB01OY  is not called if CTRL = 'N'.
-C
-C     Input/Output Parameters
-C
-C     NOBR    (input) INTEGER
-C             The number of block rows,  s,  in the input and output
-C             block Hankel matrices to be processed.  NOBR > 0.
-C             (In the MOESP theory,  NOBR  should be larger than  n,
-C             the estimated dimension of state vector.)
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C             When M = 0, no system inputs are processed.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     NSMP    (input) INTEGER
-C             The number of rows of matrices  U  and  Y  (number of
-C             samples,  t). (When sequential data processing is used,
-C             NSMP  is the number of samples of the current data
-C             block.)
-C             NSMP >= 2*(M+L+1)*NOBR - 1,  for non-sequential
-C                                          processing;
-C             NSMP >= 2*NOBR,  for sequential processing.
-C             The total number of samples when calling the routine with
-C             BATCH = 'L'  should be at least  2*(M+L+1)*NOBR - 1.
-C             The  NSMP  argument may vary from a cycle to another in
-C             sequential data processing, but  NOBR, M,  and  L  should
-C             be kept constant. For efficiency, it is advisable to use
-C             NSMP  as large as possible.
-C
-C     U       (input) DOUBLE PRECISION array, dimension (LDU,M)
-C             The leading NSMP-by-M part of this array must contain the
-C             t-by-m input-data sequence matrix  U,
-C             U = [u_1 u_2 ... u_m].  Column  j  of  U  contains the
-C             NSMP  values of the j-th input component for consecutive
-C             time increments.
-C             If M = 0, this array is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of the array U.
-C             LDU >= NSMP, if M > 0;
-C             LDU >= 1,    if M = 0.
-C
-C     Y       (input) DOUBLE PRECISION array, dimension (LDY,L)
-C             The leading NSMP-by-L part of this array must contain the
-C             t-by-l output-data sequence matrix  Y,
-C             Y = [y_1 y_2 ... y_l].  Column  j  of  Y  contains the
-C             NSMP  values of the j-th output component for consecutive
-C             time increments.
-C
-C     LDY     INTEGER
-C             The leading dimension of the array Y.  LDY >= NSMP.
-C
-C     N       (output) INTEGER
-C             The estimated order of the system.
-C             If  CTRL = 'C',  the estimated order has been reset to a
-C             value specified by the user.
-C
-C     R       (output or input/output) DOUBLE PRECISION array, dimension
-C             ( LDR,2*(M+L)*NOBR )
-C             On exit, if ALG = 'C' and BATCH = 'F' or 'I', the leading
-C             2*(M+L)*NOBR-by-2*(M+L)*NOBR upper triangular part of this
-C             array contains the current upper triangular part of the
-C             correlation matrix in sequential data processing.
-C             If ALG = 'F' and BATCH = 'F' or 'I', the array R is not
-C             referenced.
-C             On exit, if INFO = 0, ALG = 'Q', and BATCH = 'F' or 'I',
-C             the leading 2*(M+L)*NOBR-by-2*(M+L)*NOBR upper triangular
-C             part of this array contains the current upper triangular
-C             factor R from the QR factorization of the concatenated
-C             block Hankel matrices. Denote  R_ij, i,j = 1:4,  the
-C             ij submatrix of  R,  partitioned by M*NOBR,  M*NOBR,
-C             L*NOBR,  and  L*NOBR  rows and columns.
-C             On exit, if INFO = 0 and BATCH = 'L' or 'O', the leading
-C             2*(M+L)*NOBR-by-2*(M+L)*NOBR upper triangular part of
-C             this array contains the matrix S, the processed upper
-C             triangular factor R from the QR factorization of the
-C             concatenated block Hankel matrices, as required by other
-C             subroutines. Specifically, let  S_ij, i,j = 1:4,  be the
-C             ij submatrix of  S,  partitioned by M*NOBR,  L*NOBR,
-C             M*NOBR,  and  L*NOBR  rows and columns. The submatrix
-C             S_22  contains the matrix of left singular vectors needed
-C             subsequently. Useful information is stored in  S_11  and
-C             in the block-column  S_14 : S_44.  For METH = 'M' and
-C             JOBD = 'M', the upper triangular part of  S_31  contains
-C             the upper triangular factor in the QR factorization of the
-C             matrix  R_1c = [ R_12'  R_22'  R_11' ]',  and  S_12
-C             contains the corresponding leading part of the transformed
-C             matrix  R_2c = [ R_13'  R_23'  R_14' ]'.  For  METH = 'N',
-C             the subarray  S_41 : S_43  contains the transpose of the
-C             matrix contained in  S_14 : S_34.
-C             The details of the contents of R need not be known if this
-C             routine is followed by SLICOT Library routine IB01BD.
-C             On entry, if ALG = 'C', or ALG = 'Q', and BATCH = 'I' or
-C             'L', the leading  2*(M+L)*NOBR-by-2*(M+L)*NOBR  upper
-C             triangular part of this array must contain the upper
-C             triangular matrix R computed at the previous call of this
-C             routine in sequential data processing. The array R need
-C             not be set on entry if ALG = 'F' or if BATCH = 'F' or 'O'.
-C
-C     LDR     INTEGER
-C             The leading dimension of the array  R.
-C             LDR >= MAX( 2*(M+L)*NOBR, 3*M*NOBR ),
-C                                  for METH = 'M' and JOBD = 'M';
-C             LDR >= 2*(M+L)*NOBR, for METH = 'M' and JOBD = 'N' or
-C                                  for METH = 'N'.
-C
-C     SV      (output) DOUBLE PRECISION array, dimension ( L*NOBR )
-C             The singular values used to estimate the system order.
-C
-C     Tolerances
-C
-C     RCOND   DOUBLE PRECISION
-C             The tolerance to be used for estimating the rank of
-C             matrices. If the user sets  RCOND > 0,  the given value
-C             of  RCOND  is used as a lower bound for the reciprocal
-C             condition number;  an m-by-n matrix whose estimated
-C             condition number is less than  1/RCOND  is considered to
-C             be of full rank.  If the user sets  RCOND <= 0,  then an
-C             implicitly computed, default tolerance, defined by
-C             RCONDEF = m*n*EPS,  is used instead, where  EPS  is the
-C             relative machine precision (see LAPACK Library routine
-C             DLAMCH).
-C             This parameter is not used for  METH = 'M'.
-C
-C     TOL     DOUBLE PRECISION
-C             Absolute tolerance used for determining an estimate of
-C             the system order. If  TOL >= 0,  the estimate is
-C             indicated by the index of the last singular value greater
-C             than or equal to  TOL.  (Singular values less than  TOL
-C             are considered as zero.) When  TOL = 0,  an internally
-C             computed default value,  TOL = NOBR*EPS*SV(1),  is used,
-C             where  SV(1)  is the maximal singular value, and  EPS  is
-C             the relative machine precision (see LAPACK Library routine
-C             DLAMCH). When  TOL < 0,  the estimate is indicated by the
-C             index of the singular value that has the largest
-C             logarithmic gap to its successor.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK >= (M+L)*NOBR, if METH = 'N';
-C             LIWORK >= M+L, if METH = 'M' and ALG = 'F';
-C             LIWORK >= 0,   if METH = 'M' and ALG = 'C' or 'Q'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of LDWORK,  and, for  METH = 'N',  and  BATCH = 'L'  or
-C             'O',  DWORK(2)  and  DWORK(3)  contain the reciprocal
-C             condition numbers of the triangular factors of the
-C             matrices  U_f  and  r_1  [6].
-C             On exit, if  INFO = -23,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C             Let
-C             k = 0,               if CONCT = 'N' and ALG = 'C' or 'Q';
-C             k = 2*NOBR-1,        if CONCT = 'C' and ALG = 'C' or 'Q';
-C             k = 2*NOBR*(M+L+1),  if CONCT = 'N' and ALG = 'F';
-C             k = 2*NOBR*(M+L+2),  if CONCT = 'C' and ALG = 'F'.
-C             The first (M+L)*k elements of  DWORK  should be preserved
-C             during successive calls of the routine with  BATCH = 'F'
-C             or  'I',  till the final call with  BATCH = 'L'.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= (4*NOBR-2)*(M+L), if ALG = 'C', BATCH = 'F' or
-C                             'I' and CONCT = 'C';
-C             LDWORK >= 1, if ALG = 'C', BATCH = 'F' or 'I' and
-C                             CONCT = 'N';
-C             LDWORK >= max((4*NOBR-2)*(M+L), 5*L*NOBR), if METH = 'M',
-C                             ALG = 'C', BATCH = 'L' and CONCT = 'C';
-C             LDWORK >= max((2*M-1)*NOBR, (M+L)*NOBR, 5*L*NOBR),
-C                             if METH = 'M', JOBD = 'M', ALG = 'C',
-C                              BATCH = 'O', or
-C                             (BATCH = 'L' and CONCT = 'N');
-C             LDWORK >= 5*L*NOBR, if METH = 'M', JOBD = 'N', ALG = 'C',
-C                              BATCH = 'O', or
-C                             (BATCH = 'L' and CONCT = 'N');
-C             LDWORK >= 5*(M+L)*NOBR+1, if METH = 'N', ALG = 'C', and
-C                             BATCH = 'L' or 'O';
-C             LDWORK >= (M+L)*2*NOBR*(M+L+3), if ALG = 'F',
-C                             BATCH <> 'O' and CONCT = 'C';
-C             LDWORK >= (M+L)*2*NOBR*(M+L+1), if ALG = 'F',
-C                             BATCH = 'F', 'I' and CONCT = 'N';
-C             LDWORK >= (M+L)*4*NOBR*(M+L+1)+(M+L)*2*NOBR, if ALG = 'F',
-C                             BATCH = 'L' and CONCT = 'N', or
-C                             BATCH = 'O';
-C             LDWORK >= 4*(M+L)*NOBR, if ALG = 'Q', BATCH = 'F', and
-C                             LDR >= NS = NSMP - 2*NOBR + 1;
-C             LDWORK >= max(4*(M+L)*NOBR, 5*L*NOBR), if METH = 'M',
-C                             ALG = 'Q', BATCH = 'O', and LDR >= NS;
-C             LDWORK >= 5*(M+L)*NOBR+1, if METH = 'N', ALG = 'Q',
-C                             BATCH = 'O', and LDR >= NS;
-C             LDWORK >= 6*(M+L)*NOBR, if ALG = 'Q', (BATCH = 'F' or 'O',
-C                             and LDR < NS), or (BATCH = 'I' or
-C                             'L' and CONCT = 'N');
-C             LDWORK >= 4*(NOBR+1)*(M+L)*NOBR, if ALG = 'Q', BATCH = 'I'
-C                             or 'L' and CONCT = 'C'.
-C             The workspace used for ALG = 'Q' is
-C                       LDRWRK*2*(M+L)*NOBR + 4*(M+L)*NOBR,
-C             where LDRWRK = LDWORK/(2*(M+L)*NOBR) - 2; recommended
-C             value LDRWRK = NS, assuming a large enough cache size.
-C             For good performance,  LDWORK  should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  the number of 100 cycles in sequential data
-C                   processing has been exhausted without signaling
-C                   that the last block of data was get; the cycle
-C                   counter was reinitialized;
-C             = 2:  a fast algorithm was requested (ALG = 'C' or 'F'),
-C                   but it failed, and the QR algorithm was then used
-C                   (non-sequential data processing);
-C             = 3:  all singular values were exactly zero, hence  N = 0
-C                   (both input and output were identically zero);
-C             = 4:  the least squares problems with coefficient matrix
-C                   U_f,  used for computing the weighted oblique
-C                   projection (for METH = 'N'), have a rank-deficient
-C                   coefficient matrix;
-C             = 5:  the least squares problem with coefficient matrix
-C                   r_1  [6], used for computing the weighted oblique
-C                   projection (for METH = 'N'), has a rank-deficient
-C                   coefficient matrix.
-C             NOTE: the values 4 and 5 of IWARN have no significance
-C                   for the identification problem.
-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:  a fast algorithm was requested (ALG = 'C', or 'F')
-C                   in sequential data processing, but it failed; the
-C                   routine can be repeatedly called again using the
-C                   standard QR algorithm;
-C             = 2:  the singular value decomposition (SVD) algorithm did
-C                   not converge.
-C
-C     METHOD
-C
-C     The procedure consists in three main steps, the first step being
-C     performed by one of the three algorithms included.
-C
-C     1.a) For non-sequential data processing using QR algorithm, a
-C     t x 2(m+l)s  matrix H is constructed, where
-C
-C          H = [ Uf'         Up'      Y'      ],  for METH = 'M',
-C                  s+1,2s,t    1,s,t   1,2s,t
-C
-C          H = [ U'       Y'      ],              for METH = 'N',
-C                 1,2s,t   1,2s,t
-C
-C     and  Up     , Uf        , U      , and  Y        are block Hankel
-C            1,s,t    s+1,2s,t   1,2s,t        1,2s,t
-C     matrices defined in terms of the input and output data [3].
-C     A QR factorization is used to compress the data.
-C     The fast QR algorithm uses a QR factorization which exploits
-C     the block-Hankel structure. Actually, the Cholesky factor of H'*H
-C     is computed.
-C
-C     1.b) For sequential data processing using QR algorithm, the QR
-C     decomposition is done sequentially, by updating the upper
-C     triangular factor  R.  This is also performed internally if the
-C     workspace is not large enough to accommodate an entire batch.
-C
-C     1.c) For non-sequential or sequential data processing using
-C     Cholesky algorithm, the correlation matrix of input-output data is
-C     computed (sequentially, if requested), taking advantage of the
-C     block Hankel structure [7].  Then, the Cholesky factor of the
-C     correlation matrix is found, if possible.
-C
-C     2) A singular value decomposition (SVD) of a certain matrix is
-C     then computed, which reveals the order  n  of the system as the
-C     number of "non-zero" singular values. For the MOESP approach, this
-C     matrix is  [ R_24'  R_34' ]' := R(ms+1:(2m+l)s,(2m+l)s+1:2(m+l)s),
-C     where  R  is the upper triangular factor  R  constructed by SLICOT
-C     Library routine  IB01MD.  For the N4SID approach, a weighted
-C     oblique projection is computed from the upper triangular factor  R
-C     and its SVD is then found.
-C
-C     3) The singular values are compared to the given, or default TOL,
-C     and the estimated order  n  is returned, possibly after user's
-C     confirmation.
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Dewilde, P.
-C         Subspace Model Identification. Part 1: The output-error
-C         state-space model identification class of algorithms.
-C         Int. J. Control, 56, pp. 1187-1210, 1992.
-C
-C     [2] Verhaegen M.
-C         Subspace Model Identification. Part 3: Analysis of the
-C         ordinary output-error state-space model identification
-C         algorithm.
-C         Int. J. Control, 58, pp. 555-586, 1993.
-C
-C     [3] Verhaegen M.
-C         Identification of the deterministic part of MIMO state space
-C         models given in innovations form from input-output data.
-C         Automatica, Vol.30, No.1, pp.61-74, 1994.
-C
-C     [4] Van Overschee, P., and De Moor, B.
-C         N4SID: Subspace Algorithms for the Identification of
-C         Combined Deterministic-Stochastic Systems.
-C         Automatica, Vol.30, No.1, pp. 75-93, 1994.
-C
-C     [5] Peternell, K., Scherrer, W. and Deistler, M.
-C         Statistical Analysis of Novel Subspace Identification Methods.
-C         Signal Processing, 52, pp. 161-177, 1996.
-C
-C     [6] Sima, V.
-C         Subspace-based Algorithms for Multivariable System
-C         Identification.
-C         Studies in Informatics and Control, 5, pp. 335-344, 1996.
-C
-C     [7] Sima, V.
-C         Cholesky or QR Factorization for Data Compression in
-C         Subspace-based Identification ?
-C         Proceedings of the Second NICONET Workshop on ``Numerical
-C         Control Software: SLICOT, a Useful Tool in Industry'',
-C         December 3, 1999, INRIA Rocquencourt, France, pp. 75-80, 1999.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is numerically stable (when QR algorithm is
-C     used), reliable and efficient. The fast Cholesky or QR algorithms
-C     are more efficient, but the accuracy could diminish by forming the
-C     correlation matrix.
-C     The most time-consuming computational step is step 1:
-C                                        2
-C     The QR algorithm needs 0(t(2(m+l)s) ) floating point operations.
-C                                           2              3
-C     The Cholesky algorithm needs 0(2t(m+l) s)+0((2(m+l)s) ) floating
-C     point operations.
-C                                          2           3 2
-C     The fast QR algorithm needs 0(2t(m+l) s)+0(4(m+l) s ) floating
-C     point operations.
-C                                                3
-C     Step 2 of the algorithm requires 0(((m+l)s) ) floating point
-C     operations.
-C
-C     FURTHER COMMENTS
-C
-C     For ALG = 'Q', BATCH = 'O' and LDR < NS, or BATCH <> 'O', the
-C     calculations could be rather inefficient if only minimal workspace
-C     (see argument LDWORK) is provided. It is advisable to provide as
-C     much workspace as possible. Almost optimal efficiency can be
-C     obtained for  LDWORK = (NS+2)*(2*(M+L)*NOBR),  assuming that the
-C     cache size is large enough to accommodate R, U, Y, and DWORK.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Universiteit Leuven, Feb. 2000.
-C
-C     REVISIONS
-C
-C     August 2000, March 2005.
-C
-C     KEYWORDS
-C
-C     Cholesky decomposition, Hankel matrix, identification methods,
-C     multivariable systems, QR decomposition, singular value
-C     decomposition.
-C
-C     ******************************************************************
-C
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   RCOND, TOL
-      INTEGER            INFO, IWARN, L, LDR, LDU, LDWORK, LDY, M, N,
-     $                   NOBR, NSMP
-      CHARACTER          ALG, BATCH, CONCT, CTRL, JOBD, METH
-C     .. Array Arguments ..
-      INTEGER            IWORK(*)
-      DOUBLE PRECISION   DWORK(*), R(LDR, *), SV(*), U(LDU, *),
-     $                   Y(LDY, *)
-C     .. Local Scalars ..
-      INTEGER            IWARNL, LMNOBR, LNOBR, MAXWRK, MINWRK, MNOBR,
-     $                   NOBR21, NR, NS, NSMPSM
-      LOGICAL            CHALG, CONNEC, CONTRL, FIRST, FQRALG, INTERM,
-     $                   JOBDM, LAST, MOESP, N4SID, ONEBCH, QRALG
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     .. External Subroutines ..
-      EXTERNAL           IB01MD, IB01ND, IB01OD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX
-C     .. Save Statement ..
-C        MAXWRK  is used to store the optimal workspace.
-C        NSMPSM  is used to sum up the  NSMP  values for  BATCH <> 'O'.
-      SAVE               MAXWRK, NSMPSM
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode the scalar input parameters.
-C
-      MOESP  = LSAME( METH,  'M' )
-      N4SID  = LSAME( METH,  'N' )
-      FQRALG = LSAME( ALG,   'F' )
-      QRALG  = LSAME( ALG,   'Q' )
-      CHALG  = LSAME( ALG,   'C' )
-      JOBDM  = LSAME( JOBD,  'M' )
-      ONEBCH = LSAME( BATCH, 'O' )
-      FIRST  = LSAME( BATCH, 'F' ) .OR. ONEBCH
-      INTERM = LSAME( BATCH, 'I' )
-      LAST   = LSAME( BATCH, 'L' ) .OR. ONEBCH
-      CONTRL = LSAME( CTRL,  'C' )
-C
-      IF( .NOT.ONEBCH ) THEN
-         CONNEC = LSAME( CONCT, 'C' )
-      ELSE
-         CONNEC = .FALSE.
-      END IF
-C
-      MNOBR  = M*NOBR
-      LNOBR  = L*NOBR
-      LMNOBR = LNOBR  + MNOBR
-      NR     = LMNOBR + LMNOBR
-      NOBR21 = 2*NOBR - 1
-      IWARN  = 0
-      INFO   = 0
-      IF( FIRST ) THEN
-         MAXWRK = 1
-         NSMPSM = 0
-      END IF
-      NSMPSM = NSMPSM + NSMP
-C
-C     Check the scalar input parameters.
-C
-      IF( .NOT.( MOESP .OR. N4SID ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( FQRALG .OR. QRALG .OR. CHALG ) ) THEN
-         INFO = -2
-      ELSE IF( MOESP .AND. .NOT.( JOBDM .OR. LSAME( JOBD, 'N' ) ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT.( FIRST .OR. INTERM .OR. LAST ) ) THEN
-         INFO = -4
-      ELSE IF( .NOT. ONEBCH ) THEN
-         IF( .NOT.( CONNEC .OR. LSAME( CONCT, 'N' ) ) )
-     $      INFO = -5
-      END IF
-      IF( INFO.EQ.0 ) THEN
-         IF( .NOT.( CONTRL .OR. LSAME( CTRL, 'N' ) ) ) THEN
-            INFO = -6
-         ELSE IF( NOBR.LE.0 ) THEN
-            INFO = -7
-         ELSE IF( M.LT.0 ) THEN
-            INFO = -8
-         ELSE IF( L.LE.0 ) THEN
-            INFO = -9
-         ELSE IF( NSMP.LT.2*NOBR .OR.
-     $            ( LAST .AND. NSMPSM.LT.NR+NOBR21 ) ) THEN
-            INFO = -10
-         ELSE IF( LDU.LT.1 .OR. ( M.GT.0 .AND. LDU.LT.NSMP ) ) THEN
-            INFO = -12
-         ELSE IF( LDY.LT.NSMP ) THEN
-            INFO = -14
-         ELSE IF( LDR.LT.NR .OR. ( MOESP .AND. JOBDM .AND.
-     $            LDR.LT.3*MNOBR ) ) THEN
-            INFO = -17
-         ELSE
-C
-C           Compute workspace.
-C           (Note: Comments in the code beginning "Workspace:" describe
-C           the minimal amount of workspace needed at that point in the
-C           code, as well as the preferred amount for good performance.)
-C
-            NS = NSMP - NOBR21
-            IF ( CHALG ) THEN
-               IF ( .NOT.LAST ) THEN
-                  IF ( CONNEC ) THEN
-                     MINWRK = 2*( NR - M - L )
-                  ELSE
-                     MINWRK = 1
-                  END IF
-               ELSE IF ( MOESP ) THEN
-                  IF ( CONNEC .AND. .NOT.ONEBCH ) THEN
-                     MINWRK = MAX( 2*( NR - M - L ), 5*LNOBR )
-                  ELSE
-                     MINWRK = 5*LNOBR
-                     IF ( JOBDM )
-     $                  MINWRK = MAX( 2*MNOBR - NOBR, LMNOBR, MINWRK )
-                  END IF
-               ELSE
-                  MINWRK = 5*LMNOBR + 1
-               END IF
-            ELSE IF ( FQRALG ) THEN
-               IF ( .NOT.ONEBCH .AND. CONNEC ) THEN
-                  MINWRK = NR*( M + L + 3 )
-               ELSE IF ( FIRST .OR. INTERM ) THEN
-                  MINWRK = NR*( M + L + 1 )
-               ELSE
-                  MINWRK = 2*NR*( M + L + 1 ) + NR
-               END IF
-            ELSE
-               MINWRK = 2*NR
-               IF ( ONEBCH .AND. LDR.GE.NS ) THEN
-                  IF ( MOESP ) THEN
-                     MINWRK = MAX( MINWRK, 5*LNOBR )
-                  ELSE
-                     MINWRK = 5*LMNOBR + 1
-                  END IF
-               END IF
-               IF ( FIRST ) THEN
-                  IF ( LDR.LT.NS ) THEN
-                     MINWRK = MINWRK + NR
-                  END IF
-               ELSE
-                  IF ( CONNEC ) THEN
-                     MINWRK = MINWRK*( NOBR + 1 )
-                  ELSE
-                     MINWRK = MINWRK + NR
-                  END IF
-               END IF
-            END IF
-C
-            MAXWRK = MINWRK
-C
-            IF( LDWORK.LT.MINWRK ) THEN
-               INFO = -23
-               DWORK( 1 ) = MINWRK
-            END IF
-         END IF
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01AD', -INFO )
-         RETURN
-      END IF
-C
-C     Compress the input-output data.
-C     Workspace: need   c*(M+L)*NOBR, where c is a constant depending
-C                       on the algorithm and the options used
-C                       (see SLICOT Library routine IB01MD);
-C                prefer larger.
-C
-      CALL IB01MD( METH, ALG, BATCH, CONCT, NOBR, M, L, NSMP, U, LDU, Y,
-     $             LDY, R, LDR, IWORK, DWORK, LDWORK, IWARN, INFO )
-C
-      IF ( INFO.EQ.1 ) THEN
-C
-C        Error return: A fast algorithm was requested (ALG = 'C', 'F')
-C        in sequential data processing, but it failed.
-C
-         RETURN
-      END IF
-C
-      MAXWRK = MAX( MAXWRK, INT( DWORK( 1 ) ) )
-C
-      IF ( .NOT.LAST ) THEN
-C
-C        Return to get new data.
-C
-         RETURN
-      END IF
-C
-C     Find the singular value decomposition (SVD) giving the system
-C     order, and perform related preliminary calculations needed for
-C     computing the system matrices.
-C     Workspace: need   max( (2*M-1)*NOBR, (M+L)*NOBR, 5*L*NOBR ),
-C                                            if METH = 'M';
-C                            5*(M+L)*NOBR+1, if METH = 'N';
-C                prefer larger.
-C
-      CALL IB01ND( METH, JOBD, NOBR, M, L, R, LDR, SV, RCOND, IWORK,
-     $             DWORK, LDWORK, IWARNL, INFO )
-      IWARN = MAX( IWARN, IWARNL )
-C
-      IF ( INFO.EQ.2 ) THEN
-C
-C        Error return: the singular value decomposition (SVD) algorithm
-C        did not converge.
-C
-         RETURN
-      END IF
-C
-C     Estimate the system order.
-C
-      CALL IB01OD( CTRL, NOBR, L, SV, N, TOL, IWARNL, INFO )
-      IWARN = MAX( IWARN, IWARNL )
-C
-C     Return optimal workspace in  DWORK(1).
-C
-      DWORK( 1 ) = MAX( MAXWRK,  INT( DWORK( 1 ) ) )
-      RETURN
-C
-C *** Last line of IB01AD ***
-      END
--- a/extra/control-devel/src/IB01BD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,791 +0,0 @@
-      SUBROUTINE IB01BD( METH, JOB, JOBCK, NOBR, N, M, L, NSMPL, R,
-     $                   LDR, A, LDA, C, LDC, B, LDB, D, LDD, Q, LDQ,
-     $                   RY, LDRY, S, LDS, K, LDK, TOL, IWORK, DWORK,
-     $                   LDWORK, BWORK, IWARN, 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 estimate the system matrices A, C, B, and D, the noise
-C     covariance matrices Q, Ry, and S, and the Kalman gain matrix K
-C     of a linear time-invariant state space model, using the
-C     processed triangular factor R of the concatenated block Hankel
-C     matrices, provided by SLICOT Library routine IB01AD.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     METH    CHARACTER*1
-C             Specifies the subspace identification method to be used,
-C             as follows:
-C             = 'M':  MOESP  algorithm with past inputs and outputs;
-C             = 'N':  N4SID  algorithm;
-C             = 'C':  combined method:  MOESP  algorithm for finding the
-C                     matrices A and C, and  N4SID  algorithm for
-C                     finding the matrices B and D.
-C
-C     JOB     CHARACTER*1
-C             Specifies which matrices should be computed, as follows:
-C             = 'A':  compute all system matrices, A, B, C, and D;
-C             = 'C':  compute the matrices A and C only;
-C             = 'B':  compute the matrix B only;
-C             = 'D':  compute the matrices B and D only.
-C
-C     JOBCK   CHARACTER*1
-C             Specifies whether or not the covariance matrices and the
-C             Kalman gain matrix are to be computed, as follows:
-C             = 'C':  the covariance matrices only should be computed;
-C             = 'K':  the covariance matrices and the Kalman gain
-C                     matrix should be computed;
-C             = 'N':  the covariance matrices and the Kalman gain matrix
-C                     should not be computed.
-C
-C     Input/Output Parameters
-C
-C     NOBR    (input) INTEGER
-C             The number of block rows,  s,  in the input and output
-C             Hankel matrices processed by other routines.  NOBR > 1.
-C
-C     N       (input) INTEGER
-C             The order of the system.  NOBR > N > 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     NSMPL   (input) INTEGER
-C             If  JOBCK = 'C' or 'K',  the total number of samples used
-C             for calculating the covariance matrices.
-C             NSMPL >= 2*(M+L)*NOBR.
-C             This parameter is not meaningful if  JOBCK = 'N'.
-C
-C     R       (input/workspace) DOUBLE PRECISION array, dimension
-C             ( LDR,2*(M+L)*NOBR )
-C             On entry, the leading  2*(M+L)*NOBR-by-2*(M+L)*NOBR  part
-C             of this array must contain the relevant data for the MOESP
-C             or N4SID algorithms, as constructed by SLICOT Library
-C             routine IB01AD. Let  R_ij,  i,j = 1:4,  be the
-C             ij submatrix of  R  (denoted  S  in IB01AD),  partitioned
-C             by  M*NOBR,  L*NOBR,  M*NOBR,  and  L*NOBR  rows and
-C             columns. The submatrix  R_22  contains the matrix of left
-C             singular vectors used. Also needed, for  METH = 'N'  or
-C             JOBCK <> 'N',  are the submatrices  R_11,  R_14 : R_44,
-C             and, for  METH = 'M' or 'C'  and  JOB <> 'C', the
-C             submatrices  R_31  and  R_12,  containing the processed
-C             matrices  R_1c  and  R_2c,  respectively, as returned by
-C             SLICOT Library routine IB01AD.
-C             Moreover, if  METH = 'N'  and  JOB = 'A' or 'C',  the
-C             block-row  R_41 : R_43  must contain the transpose of the
-C             block-column  R_14 : R_34  as returned by SLICOT Library
-C             routine IB01AD.
-C             The remaining part of  R  is used as workspace.
-C             On exit, part of this array is overwritten. Specifically,
-C             if  METH = 'M',  R_22  and  R_31  are overwritten if
-C                 JOB = 'B' or 'D',  and  R_12,  R_22,  R_14 : R_34,
-C                 and possibly  R_11  are overwritten if  JOBCK <> 'N';
-C             if  METH = 'N',  all needed submatrices are overwritten.
-C             The details of the contents of  R  need not be known if
-C             this routine is called once just after calling the SLICOT
-C             Library routine IB01AD.
-C
-C     LDR     INTEGER
-C             The leading dimension of the array  R.
-C             LDR >= 2*(M+L)*NOBR.
-C
-C     A       (input or output) DOUBLE PRECISION array, dimension
-C             (LDA,N)
-C             On entry, if  METH = 'N' or 'C'  and  JOB = 'B' or 'D',
-C             the leading N-by-N part of this array must contain the
-C             system state matrix.
-C             If  METH = 'M'  or  (METH = 'N' or 'C'  and JOB = 'A'
-C             or 'C'),  this array need not be set on input.
-C             On exit, if  JOB = 'A' or 'C'  and  INFO = 0,  the
-C             leading N-by-N part of this array contains the system
-C             state matrix.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.
-C             LDA >= N,  if  JOB = 'A' or 'C',  or  METH = 'N' or 'C'
-C                            and  JOB = 'B' or 'D';
-C             LDA >= 1,  otherwise.
-C
-C     C       (input or output) DOUBLE PRECISION array, dimension
-C             (LDC,N)
-C             On entry, if  METH = 'N' or 'C'  and  JOB = 'B' or 'D',
-C             the leading L-by-N part of this array must contain the
-C             system output matrix.
-C             If  METH = 'M'  or  (METH = 'N' or 'C'  and JOB = 'A'
-C             or 'C'),  this array need not be set on input.
-C             On exit, if  JOB = 'A' or 'C'  and  INFO = 0,  or
-C             INFO = 3  (or  INFO >= 0,  for  METH = 'M'),  the leading
-C             L-by-N part of this array contains the system output
-C             matrix.
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.
-C             LDC >= L,  if  JOB = 'A' or 'C',  or  METH = 'N' or 'C'
-C                            and  JOB = 'B' or 'D';
-C             LDC >= 1,  otherwise.
-C
-C     B       (output) DOUBLE PRECISION array, dimension (LDB,M)
-C             If  M > 0,  JOB = 'A', 'B', or 'D'  and  INFO = 0,  the
-C             leading N-by-M part of this array contains the system
-C             input matrix. If  M = 0  or  JOB = 'C',  this array is
-C             not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.
-C             LDB >= N,  if M > 0 and JOB = 'A', 'B', or 'D';
-C             LDB >= 1,  if M = 0 or  JOB = 'C'.
-C
-C     D       (output) DOUBLE PRECISION array, dimension (LDD,M)
-C             If  M > 0,  JOB = 'A' or 'D'  and  INFO = 0,  the leading
-C             L-by-M part of this array contains the system input-output
-C             matrix. If  M = 0  or  JOB = 'C' or 'B',  this array is
-C             not referenced.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.
-C             LDD >= L,  if M > 0 and JOB = 'A' or 'D';
-C             LDD >= 1,  if M = 0 or  JOB = 'C' or 'B'.
-C
-C     Q       (output) DOUBLE PRECISION array, dimension (LDQ,N)
-C             If  JOBCK = 'C' or 'K',  the leading N-by-N part of this
-C             array contains the positive semidefinite state covariance
-C             matrix. If  JOBCK = 'K',  this matrix has been used as
-C             state weighting matrix for computing the Kalman gain.
-C             This parameter is not referenced if JOBCK = 'N'.
-C
-C     LDQ     INTEGER
-C             The leading dimension of the array Q.
-C             LDQ >= N,  if JOBCK = 'C' or 'K';
-C             LDQ >= 1,  if JOBCK = 'N'.
-C
-C     RY      (output) DOUBLE PRECISION array, dimension (LDRY,L)
-C             If  JOBCK = 'C' or 'K',  the leading L-by-L part of this
-C             array contains the positive (semi)definite output
-C             covariance matrix. If  JOBCK = 'K',  this matrix has been
-C             used as output weighting matrix for computing the Kalman
-C             gain.
-C             This parameter is not referenced if JOBCK = 'N'.
-C
-C     LDRY    INTEGER
-C             The leading dimension of the array RY.
-C             LDRY >= L,  if JOBCK = 'C' or 'K';
-C             LDRY >= 1,  if JOBCK = 'N'.
-C
-C     S       (output) DOUBLE PRECISION array, dimension (LDS,L)
-C             If  JOBCK = 'C' or 'K',  the leading N-by-L part of this
-C             array contains the state-output cross-covariance matrix.
-C             If  JOBCK = 'K',  this matrix has been used as state-
-C             output weighting matrix for computing the Kalman gain.
-C             This parameter is not referenced if JOBCK = 'N'.
-C
-C     LDS     INTEGER
-C             The leading dimension of the array S.
-C             LDS >= N,  if JOBCK = 'C' or 'K';
-C             LDS >= 1,  if JOBCK = 'N'.
-C
-C     K       (output) DOUBLE PRECISION array, dimension ( LDK,L )
-C             If  JOBCK = 'K',  the leading  N-by-L  part of this array
-C             contains the estimated Kalman gain matrix.
-C             If  JOBCK = 'C' or 'N',  this array is not referenced.
-C
-C     LDK     INTEGER
-C             The leading dimension of the array  K.
-C             LDK >= N,  if JOBCK = 'K';
-C             LDK >= 1,  if JOBCK = 'C' or 'N'.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used for estimating the rank of
-C             matrices. If the user sets  TOL > 0,  then the given value
-C             of  TOL  is used as a lower bound for the reciprocal
-C             condition number;  an m-by-n matrix whose estimated
-C             condition number is less than  1/TOL  is considered to
-C             be of full rank.  If the user sets  TOL <= 0,  then an
-C             implicitly computed, default tolerance, defined by
-C             TOLDEF = m*n*EPS,  is used instead, where  EPS  is the
-C             relative machine precision (see LAPACK Library routine
-C             DLAMCH).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK >= max(LIW1,LIW2), where
-C             LIW1 = N,                     if METH <> 'N' and M = 0
-C                                        or JOB = 'C' and JOBCK = 'N';
-C             LIW1 = M*NOBR+N,              if METH <> 'N', JOB = 'C',
-C                                           and JOBCK <> 'N';
-C             LIW1 = max(L*NOBR,M*NOBR),    if METH = 'M', JOB <> 'C',
-C                                           and JOBCK = 'N';
-C             LIW1 = max(L*NOBR,M*NOBR+N),  if METH = 'M', JOB <> 'C',
-C                                           and JOBCK = 'C' or 'K';
-C             LIW1 = max(M*NOBR+N,M*(N+L)), if METH = 'N', or METH = 'C'
-C                                           and JOB  <> 'C';
-C             LIW2 = 0,                     if JOBCK <> 'K';
-C             LIW2 = N*N,                   if JOBCK =  'K'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of LDWORK,  and  DWORK(2),  DWORK(3),  DWORK(4),  and
-C             DWORK(5)  contain the reciprocal condition numbers of the
-C             triangular factors of the following matrices (defined in
-C             SLICOT Library routine IB01PD and in the lower level
-C             routines):
-C                GaL  (GaL = Un(1:(s-1)*L,1:n)),
-C                R_1c (if  METH = 'M' or 'C'),
-C                M    (if  JOBCK = 'C' or 'K'  or  METH = 'N'),  and
-C                Q or T  (see SLICOT Library routine IB01PY or IB01PX),
-C             respectively.
-C             If  METH = 'N',  DWORK(3)  is set to one without any
-C             calculations. Similarly, if  METH = 'M'  and  JOBCK = 'N',
-C             DWORK(4)  is set to one. If  M = 0  or  JOB = 'C',
-C             DWORK(3)  and  DWORK(5)  are set to one.
-C             If  JOBCK = 'K'  and  INFO = 0,  DWORK(6)  to  DWORK(13)
-C             contain information about the accuracy of the results when
-C             computing the Kalman gain matrix, as follows:
-C                DWORK(6)  - reciprocal condition number of the matrix
-C                            U11  of the Nth order system of algebraic
-C                            equations from which the solution matrix  X
-C                            of the Riccati equation is obtained;
-C                DWORK(7)  - reciprocal pivot growth factor for the LU
-C                            factorization of the matrix  U11;
-C                DWORK(8)  - reciprocal condition number of the matrix
-C                            As = A - S*inv(Ry)*C,  which is inverted by
-C                            the standard Riccati solver;
-C                DWORK(9)  - reciprocal pivot growth factor for the LU
-C                            factorization of the matrix  As;
-C                DWORK(10) - reciprocal condition number of the matrix
-C                            Ry;
-C                DWORK(11) - reciprocal condition number of the matrix
-C                            Ry + C*X*C';
-C                DWORK(12) - reciprocal condition number for the Riccati
-C                            equation solution;
-C                DWORK(13) - forward error bound for the Riccati
-C                            equation solution.
-C             On exit, if  INFO = -30,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= max( LDW1,LDW2,LDW3 ), where, if METH = 'M',
-C             LDW1 >= max( 2*(L*NOBR-L)*N+2*N, (L*NOBR-L)*N+N*N+7*N ),
-C                     if JOB = 'C' or JOB = 'A' and M = 0;
-C             LDW1 >= max( 2*(L*NOBR-L)*N+N*N+7*N,
-C                          (L*NOBR-L)*N+N+6*M*NOBR, (L*NOBR-L)*N+N+
-C                          max( L+M*NOBR, L*NOBR +
-C                                         max( 3*L*NOBR+1, M ) ) ),
-C                     if M > 0 and JOB = 'A', 'B', or 'D';
-C             LDW2 >= 0,                          if JOBCK = 'N';
-C             LDW2 >= L*NOBR*N+
-C                     max( (L*NOBR-L)*N+Aw+2*N+max(5*N,(2*M+L)*NOBR+L),
-C                          4*(M*NOBR+N)+1, M*NOBR+2*N+L ),
-C                                                 if JOBCK = 'C' or 'K',
-C             where Aw = N+N*N, if M = 0 or JOB = 'C';
-C                   Aw = 0,     otherwise;
-C             if METH = 'N',
-C             LDW1 >= L*NOBR*N+max( (L*NOBR-L)*N+2*N+(2*M+L)*NOBR+L,
-C                                   2*(L*NOBR-L)*N+N*N+8*N,
-C                                   N+4*(M*NOBR+N)+1, M*NOBR+3*N+L );
-C             LDW2 >= 0, if M = 0 or JOB = 'C';
-C             LDW2 >= L*NOBR*N+M*NOBR*(N+L)*(M*(N+L)+1)+
-C                                max( (N+L)**2, 4*M*(N+L)+1 ),
-C                     if M > 0 and JOB = 'A', 'B', or 'D';
-C             and, if METH = 'C', LDW1 as
-C             max( LDW1 for METH = 'M', JOB = 'C', LDW1 for METH = 'N'),
-C             and LDW2 for METH = 'N' are used;
-C             LDW3 >= 0,                     if JOBCK <> 'K';
-C             LDW3 >= max(  4*N*N+2*N*L+L*L+max( 3*L,N*L ),
-C                          14*N*N+12*N+5 ),  if JOBCK =  'K'.
-C             For good performance,  LDWORK  should be larger.
-C
-C     BWORK   LOGICAL array, dimension (LBWORK)
-C             LBWORK = 2*N, if JOBCK =  'K';
-C             LBWORK = 0,   if JOBCK <> 'K'.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 4:  a least squares problem to be solved has a
-C                   rank-deficient coefficient matrix;
-C             = 5:  the computed covariance matrices are too small.
-C                   The problem seems to be a deterministic one; the
-C                   gain matrix is set to zero.
-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             = 2:  the singular value decomposition (SVD) algorithm did
-C                   not converge;
-C             = 3:  a singular upper triangular matrix was found;
-C             = 3+i:  if  JOBCK = 'K'  and the associated Riccati
-C                   equation could not be solved, where i = 1,...,6;
-C                   (see the description of the parameter INFO for the
-C                   SLICOT Library routine SB02RD for the meaning of
-C                   the i values);
-C             = 10: the QR algorithm did not converge.
-C
-C     METHOD
-C
-C     In the MOESP approach, the matrices  A  and  C  are first
-C     computed from an estimated extended observability matrix [1],
-C     and then, the matrices  B  and  D  are obtained by solving an
-C     extended linear system in a least squares sense.
-C     In the N4SID approach, besides the estimated extended
-C     observability matrix, the solutions of two least squares problems
-C     are used to build another least squares problem, whose solution
-C     is needed to compute the system matrices  A,  C,  B,  and  D.  The
-C     solutions of the two least squares problems are also optionally
-C     used by both approaches to find the covariance matrices.
-C     The Kalman gain matrix is obtained by solving a discrete-time
-C     algebraic Riccati equation.
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Dewilde, P.
-C         Subspace Model Identification. Part 1: The output-error
-C         state-space model identification class of algorithms.
-C         Int. J. Control, 56, pp. 1187-1210, 1992.
-C
-C     [2] Van Overschee, P., and De Moor, B.
-C         N4SID: Two Subspace Algorithms for the Identification
-C         of Combined Deterministic-Stochastic Systems.
-C         Automatica, Vol.30, No.1, pp. 75-93, 1994.
-C
-C     [3] Van Overschee, P.
-C         Subspace Identification : Theory - Implementation -
-C         Applications.
-C         Ph. D. Thesis, Department of Electrical Engineering,
-C         Katholieke Universiteit Leuven, Belgium, Feb. 1995.
-C
-C     [4] Sima, V.
-C         Subspace-based Algorithms for Multivariable System
-C         Identification.
-C         Studies in Informatics and Control, 5, pp. 335-344, 1996.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method consists in numerically stable steps.
-C
-C     FURTHER COMMENTS
-C
-C     The covariance matrices are computed using the N4SID approach.
-C     Therefore, for efficiency reasons, it is advisable to set
-C     METH = 'N',  if the Kalman gain matrix or covariance matrices
-C     are needed  (JOBCK = 'K', or 'C').  When  JOBCK = 'N',  it could
-C     be more efficient to use the combined method,  METH = 'C'.
-C     Often, this combination will also provide better accuracy than
-C     MOESP algorithm.
-C     In some applications, it is useful to compute the system matrices
-C     using two calls to this routine, the first one with  JOB = 'C',
-C     and the second one with  JOB = 'B' or 'D'.  This is slightly less
-C     efficient than using a single call with  JOB = 'A',  because some
-C     calculations are repeated. If  METH = 'N',  all the calculations
-C     at the first call are performed again at the second call;
-C     moreover, it is required to save the needed submatrices of  R
-C     before the first call and restore them before the second call.
-C     If the covariance matrices and/or the Kalman gain are desired,
-C     JOBCK  should be set to  'C'  or  'K'  at the second call.
-C     If  B  and  D  are both needed, they should be computed at once.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Dec. 1999.
-C
-C     REVISIONS
-C
-C     March 2000, August 2000, Sept. 2001, March 2005.
-C
-C     KEYWORDS
-C
-C     Identification methods; least squares solutions; multivariable
-C     systems; QR decomposition; singular value decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO  = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   TOL
-      INTEGER            INFO, IWARN, L, LDA, LDB, LDC, LDD, LDK, LDQ,
-     $                   LDR, LDRY, LDS, LDWORK, M, N, NOBR, NSMPL
-      CHARACTER          JOB, JOBCK, METH
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA, *), B(LDB, *), C(LDC, *), D(LDD, *),
-     $                   DWORK(*),  K(LDK, *), Q(LDQ, *), R(LDR, *),
-     $                   RY(LDRY, *), S(LDS, *)
-      INTEGER            IWORK( * )
-      LOGICAL            BWORK( * )
-C     .. Local Scalars ..
-      DOUBLE PRECISION   FERR, RCOND, RCONDR, RNORM, SEP
-      INTEGER            I, IA, IAW, IC, ID, IERR, IFACT, IG, IK, IO,
-     $                   IQ, IR, IS, IT, IV, IWARNL, IWI, IWR, IX,
-     $                   JWORK, LDUNN, LL, LMMNOL, LMNOBR, LNOBR,
-     $                   MAXWRK, MINWRK, MNOBR, MNOBRN, N2, NL, NN, NPL,
-     $                   NR
-      CHARACTER          JOBBD, JOBCOV, JOBCV
-      LOGICAL            COMBIN, MOESP, N4SID, WITHAL, WITHB, WITHC,
-     $                   WITHCO, WITHD, WITHK
-C     .. Local Arrays ..
-      DOUBLE PRECISION   RCND(8)
-      INTEGER            OUFACT(2)
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DLACPY, DLASET, IB01PD, MA02AD, SB02MT, SB02ND,
-     $                   SB02RD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          INT, MAX
-C     .. Executable Statements ..
-C
-C     Decode the scalar input parameters.
-C
-      MOESP  = LSAME( METH,  'M' )
-      N4SID  = LSAME( METH,  'N' )
-      COMBIN = LSAME( METH,  'C' )
-      WITHAL = LSAME( JOB,   'A' )
-      WITHC  = LSAME( JOB,   'C' ) .OR. WITHAL
-      WITHD  = LSAME( JOB,   'D' ) .OR. WITHAL
-      WITHB  = LSAME( JOB,   'B' ) .OR. WITHD
-      WITHK  = LSAME( JOBCK, 'K' )
-      WITHCO = LSAME( JOBCK, 'C' ) .OR. WITHK
-      MNOBR  = M*NOBR
-      LNOBR  = L*NOBR
-      LMNOBR = LNOBR + MNOBR
-      MNOBRN = MNOBR + N
-      LDUNN  = ( LNOBR - L )*N
-      LMMNOL = LNOBR + 2*MNOBR + L
-      NR     = LMNOBR + LMNOBR
-      NPL    = N + L
-      N2     = N + N
-      NN     = N*N
-      NL     = N*L
-      LL     = L*L
-      MINWRK = 1
-      IWARN  = 0
-      INFO   = 0
-C
-C     Check the scalar input parameters.
-C
-      IF( .NOT.( MOESP .OR. N4SID .OR. COMBIN ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( WITHB .OR. WITHC ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.( WITHCO .OR. LSAME( JOBCK, 'N' ) ) ) THEN
-         INFO = -3
-      ELSE IF( NOBR.LE.1 ) THEN
-         INFO = -4
-      ELSE IF( N.LE.0 .OR. N.GE.NOBR ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( L.LE.0 ) THEN
-         INFO = -7
-      ELSE IF( WITHCO .AND. NSMPL.LT.NR ) THEN
-         INFO = -8
-      ELSE IF( LDR.LT.NR ) THEN
-         INFO = -10
-      ELSE IF( LDA.LT.1 .OR. ( ( WITHC .OR. ( WITHB .AND. .NOT.MOESP ) )
-     $   .AND. LDA.LT.N ) ) THEN
-         INFO = -12
-      ELSE IF( LDC.LT.1 .OR. ( ( WITHC .OR. ( WITHB .AND. .NOT.MOESP ) )
-     $   .AND. LDC.LT.L ) ) THEN
-         INFO = -14
-      ELSE IF( LDB.LT.1  .OR. ( WITHB  .AND. LDB.LT.N .AND. M.GT.0 ) )
-     $      THEN
-         INFO = -16
-      ELSE IF( LDD.LT.1  .OR. ( WITHD  .AND. LDD.LT.L .AND. M.GT.0 ) )
-     $      THEN
-         INFO = -18
-      ELSE IF( LDQ.LT.1  .OR. ( WITHCO .AND. LDQ.LT.N ) )  THEN
-         INFO = -20
-      ELSE IF( LDRY.LT.1 .OR. ( WITHCO .AND. LDRY.LT.L ) ) THEN
-         INFO = -22
-      ELSE IF( LDS.LT.1  .OR. ( WITHCO .AND. LDS.LT.N ) )  THEN
-         INFO = -24
-      ELSE IF( LDK.LT.1  .OR. ( WITHK  .AND. LDK.LT.N ) )  THEN
-         INFO = -26
-      ELSE
-C
-C        Compute workspace.
-C        (Note: Comments in the code beginning "Workspace:" describe the
-C         minimal amount of workspace needed at that point in the code,
-C         as well as the preferred amount for good performance.)
-C
-         IAW    = 0
-         MINWRK = LDUNN + 4*N
-         IF( .NOT.N4SID ) THEN
-            ID = 0
-            IF( WITHC ) THEN
-               MINWRK = MAX( MINWRK, 2*LDUNN + N2, LDUNN + NN + 7*N )
-            END IF
-         ELSE
-            ID = N
-         END IF
-C
-         IF( ( M.GT.0 .AND. WITHB ) .OR. .NOT.MOESP ) THEN
-            MINWRK = MAX( MINWRK, 2*LDUNN + NN + ID + 7*N )
-            IF ( MOESP )
-     $         MINWRK = MAX( MINWRK, LDUNN + N + 6*MNOBR, LDUNN + N +
-     $                       MAX( L + MNOBR, LNOBR +
-     $                                       MAX( 3*LNOBR + 1, M ) ) )
-         ELSE
-            IF( .NOT.N4SID )
-     $         IAW = N + NN
-         END IF
-C
-         IF( .NOT.MOESP .OR. WITHCO ) THEN
-            MINWRK = MAX( MINWRK, LDUNN + IAW + N2 + MAX( 5*N, LMMNOL ),
-     $                    ID + 4*MNOBRN + 1, ID + MNOBRN + NPL )
-            IF( .NOT.MOESP .AND. M.GT.0 .AND. WITHB )
-     $         MINWRK = MAX( MINWRK, MNOBR*NPL*( M*NPL + 1 ) +
-     $                       MAX( NPL**2, 4*M*NPL + 1 ) )
-            MINWRK = LNOBR*N + MINWRK
-         END IF
-C
-         IF( WITHK ) THEN
-            MINWRK = MAX( MINWRK, 4*NN + 2*NL + LL + MAX( 3*L, NL ),
-     $                    14*NN + 12*N + 5 )
-         END IF
-C
-         IF ( LDWORK.LT.MINWRK ) THEN
-            INFO = -30
-            DWORK( 1 ) = MINWRK
-         END IF
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01BD', -INFO )
-         RETURN
-      END IF
-C
-      IF ( .NOT.WITHK ) THEN
-         JOBCV = JOBCK
-      ELSE
-         JOBCV = 'C'
-      END IF
-C
-      IO = 1
-      IF ( .NOT.MOESP .OR. WITHCO ) THEN
-         JWORK = IO + LNOBR*N
-      ELSE
-         JWORK = IO
-      END IF
-      MAXWRK = MINWRK
-C
-C     Call the computational routine for estimating system matrices.
-C
-      IF ( .NOT.COMBIN ) THEN
-         CALL IB01PD( METH, JOB, JOBCV, NOBR, N, M, L, NSMPL, R, LDR,
-     $                A, LDA, C, LDC, B, LDB, D, LDD, Q, LDQ, RY, LDRY,
-     $                S, LDS, DWORK(IO), LNOBR, TOL, IWORK,
-     $                DWORK(JWORK), LDWORK-JWORK+1, IWARN, INFO )
-C
-      ELSE
-C
-         IF ( WITHC ) THEN
-            IF ( WITHAL ) THEN
-               JOBCOV = 'N'
-            ELSE
-               JOBCOV = JOBCV
-            END IF
-            CALL IB01PD( 'MOESP', 'C and A', JOBCOV, NOBR, N, M, L,
-     $                   NSMPL, R, LDR, A, LDA, C, LDC, B, LDB, D, LDD,
-     $                   Q, LDQ, RY, LDRY, S, LDS, DWORK(IO), LNOBR,
-     $                   TOL, IWORK, DWORK(JWORK), LDWORK-JWORK+1,
-     $                   IWARNL, INFO )
-            IF ( INFO.NE.0 )
-     $         RETURN
-            IWARN  = MAX( IWARN, IWARNL )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-         END IF
-C
-         IF ( WITHB ) THEN
-            IF ( .NOT.WITHAL ) THEN
-               JOBBD = JOB
-            ELSE
-               JOBBD = 'D'
-            END IF
-            CALL IB01PD( 'N4SID', JOBBD, JOBCV, NOBR, N, M, L, NSMPL, R,
-     $                LDR, A, LDA, C, LDC, B, LDB, D, LDD, Q, LDQ,
-     $                RY, LDRY, S, LDS, DWORK(IO), LNOBR, TOL, IWORK,
-     $                DWORK(JWORK), LDWORK-JWORK+1, IWARNL, INFO )
-            IWARN  = MAX( IWARN, IWARNL )
-         END IF
-      END IF
-C
-      IF ( INFO.NE.0 )
-     $   RETURN
-      MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-      DO 10 I = 1, 4
-         RCND(I) = DWORK(JWORK+I)
-   10 CONTINUE
-C
-      IF ( WITHK ) THEN
-         IF ( IWARN.EQ.5 ) THEN
-C
-C           The problem seems to be a deterministic one. Set the Kalman
-C           gain to zero, set accuracy parameters and return.
-C
-            CALL DLASET( 'Full', N, L, ZERO, ZERO, K, LDK )
-C
-            DO 20 I = 6, 12
-               DWORK(I) = ONE
-   20       CONTINUE
-C
-            DWORK(13) = ZERO
-         ELSE
-C
-C           Compute the Kalman gain matrix.
-C
-C           Convert the optimal problem with coupling weighting terms
-C           to a standard problem.
-C           Workspace:  need   4*N*N+2*N*L+L*L+max( 3*L,N*L );
-C                       prefer larger.
-C
-            IX    = 1
-            IQ    = IX + NN
-            IA    = IQ + NN
-            IG    = IA + NN
-            IC    = IG + NN
-            IR    = IC + NL
-            IS    = IR + LL
-            JWORK = IS + NL
-C
-            CALL MA02AD( 'Full',  N, N, A,  LDA,  DWORK(IA), N )
-            CALL MA02AD( 'Full',  L, N, C,  LDC,  DWORK(IC), N )
-            CALL DLACPY( 'Upper', N, N, Q,  LDQ,  DWORK(IQ), N )
-            CALL DLACPY( 'Upper', L, L, RY, LDRY, DWORK(IR), L )
-            CALL DLACPY( 'Full',  N, L, S,  LDS,  DWORK(IS), N )
-C
-            CALL SB02MT( 'G needed', 'Nonzero S', 'Not factored',
-     $                   'Upper', N, L, DWORK(IA), N, DWORK(IC), N,
-     $                   DWORK(IQ), N, DWORK(IR), L, DWORK(IS), N,
-     $                   IWORK, IFACT, DWORK(IG), N, IWORK(L+1),
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            IF ( IERR.NE.0 ) THEN
-               INFO = 3
-               RETURN
-            END IF
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-            RCONDR = DWORK(JWORK+1)
-C
-C           Solve the Riccati equation.
-C           Workspace:  need   14*N*N+12*N+5;
-C                       prefer larger.
-C
-            IT    = IC
-            IV    = IT  + NN
-            IWR   = IV  + NN
-            IWI   = IWR + N2
-            IS    = IWI + N2
-            JWORK = IS  + N2*N2
-C
-            CALL SB02RD( 'All', 'Discrete', 'Direct', 'NoTranspose',
-     $                   'Upper', 'General scaling', 'Unstable first',
-     $                   'Not factored', 'Reduced', N, DWORK(IA), N,
-     $                   DWORK(IT), N, DWORK(IV), N, DWORK(IG), N,
-     $                   DWORK(IQ), N, DWORK(IX), N, SEP, RCOND, FERR,
-     $                   DWORK(IWR), DWORK(IWI), DWORK(IS), N2, IWORK,
-     $                   DWORK(JWORK), LDWORK-JWORK+1, BWORK, IERR )
-C
-            IF ( IERR.NE.0 .AND. IERR.LT.7 ) THEN
-               INFO = IERR + 3
-               RETURN
-            END IF
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-            DO 30 I = 1, 4
-               RCND(I+4) = DWORK(JWORK+I)
-   30       CONTINUE
-C
-C           Compute the gain matrix.
-C           Workspace:  need   2*N*N+2*N*L+L*L+3*L;
-C                       prefer larger.
-C
-            IA    = IX + NN
-            IC    = IA + NN
-            IR    = IC + NL
-            IK    = IR + LL
-            JWORK = IK + NL
-C
-            CALL MA02AD( 'Full',  N, N, A,  LDA,  DWORK(IA), N )
-            CALL MA02AD( 'Full',  L, N, C,  LDC,  DWORK(IC), N )
-            CALL DLACPY( 'Upper', L, L, RY, LDRY, DWORK(IR), L )
-C
-            CALL SB02ND( 'Discrete', 'NotFactored', 'Upper',
-     $                   'Nonzero S', N, L, 0, DWORK(IA), N, DWORK(IC),
-     $                   N, DWORK(IR), L, IWORK, S, LDS, DWORK(IX), N,
-     $                   RNORM, DWORK(IK), L, OUFACT, IWORK(L+1),
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-            IF ( IERR.NE.0 ) THEN
-               IF ( IERR.LE.L+1 ) THEN
-                  INFO = 3
-               ELSE IF ( IERR.EQ.L+2 ) THEN
-                  INFO = 10
-               END IF
-               RETURN
-            END IF
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-            CALL MA02AD( 'Full', L, N, DWORK(IK), L, K, LDK )
-C
-C           Set the accuracy parameters.
-C
-            DWORK(11) = DWORK(JWORK+1)
-C
-            DO 40 I = 6, 9
-               DWORK(I) = RCND(I-1)
-   40       CONTINUE
-C
-            DWORK(10) = RCONDR
-            DWORK(12) = RCOND
-            DWORK(13) = FERR
-         END IF
-      END IF
-C
-C     Return optimal workspace in  DWORK(1)  and the remaining
-C     reciprocal condition numbers in the next locations.
-C
-      DWORK(1) = MAXWRK
-C
-      DO 50 I = 2, 5
-         DWORK(I) = RCND(I-1)
-   50 CONTINUE
-C
-      RETURN
-C
-C *** Last line of IB01BD ***
-      END
--- a/extra/control-devel/src/IB01CD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,823 +0,0 @@
-      SUBROUTINE IB01CD( JOBX0, COMUSE, JOB, N, M, L, NSMP, A, LDA, B,
-     $                   LDB, C, LDC, D, LDD, U, LDU, Y, LDY, X0, V,
-     $                   LDV, TOL, IWORK, DWORK, LDWORK, IWARN, 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 estimate the initial state and, optionally, the system matrices
-C     B  and  D  of a linear time-invariant (LTI) discrete-time system,
-C     given the system matrices  (A,B,C,D),  or (when  B  and  D  are
-C     estimated) only the matrix pair  (A,C),  and the input and output
-C     trajectories of the system. The model structure is :
-C
-C           x(k+1) = Ax(k) + Bu(k),   k >= 0,
-C           y(k)   = Cx(k) + Du(k),
-C
-C     where  x(k)  is the  n-dimensional state vector (at time k),
-C            u(k)  is the  m-dimensional input vector,
-C            y(k)  is the  l-dimensional output vector,
-C     and  A, B, C, and D  are real matrices of appropriate dimensions.
-C     The input-output data can internally be processed sequentially.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBX0   CHARACTER*1
-C             Specifies whether or not the initial state should be
-C             computed, as follows:
-C             = 'X':  compute the initial state x(0);
-C             = 'N':  do not compute the initial state (possibly,
-C                     because x(0) is known to be zero).
-C
-C     COMUSE  CHARACTER*1
-C             Specifies whether the system matrices B and D should be
-C             computed or used, as follows:
-C             = 'C':  compute the system matrices B and D, as specified
-C                     by JOB;
-C             = 'U':  use the system matrices B and D, as specified by
-C                     JOB;
-C             = 'N':  do not compute/use the matrices B and D.
-C             If  JOBX0 = 'N'  and  COMUSE <> 'N',  then  x(0)  is set
-C             to zero.
-C             If  JOBX0 = 'N'  and  COMUSE =  'N',  then  x(0)  is
-C             neither computed nor set to zero.
-C
-C     JOB     CHARACTER*1
-C             If  COMUSE = 'C'  or  'U',  specifies which of the system
-C             matrices  B and D  should be computed or used, as follows:
-C             = 'B':  compute/use the matrix B only (D is known to be
-C                     zero);
-C             = 'D':  compute/use the matrices B and D.
-C             The value of  JOB  is irrelevant if  COMUSE = 'N'  or if
-C             JOBX0 = 'N'  and  COMUSE = 'U'.
-C             The combinations of options, the data used, and the
-C             returned results, are given in the table below, where
-C             '*'  denotes an irrelevant value.
-C
-C              JOBX0   COMUSE    JOB     Data used    Returned results
-C             ----------------------------------------------------------
-C                X       C        B       A,C,u,y          x,B
-C                X       C        D       A,C,u,y          x,B,D
-C                N       C        B       A,C,u,y          x=0,B
-C                N       C        D       A,C,u,y          x=0,B,D
-C             ----------------------------------------------------------
-C                X       U        B      A,B,C,u,y            x
-C                X       U        D      A,B,C,D,u,y          x
-C                N       U        *          -               x=0
-C             ----------------------------------------------------------
-C                X       N        *        A,C,y              x
-C                N       N        *          -                -
-C             ----------------------------------------------------------
-C
-C             For  JOBX0 = 'N'  and  COMUSE = 'N',  the routine just
-C             sets  DWORK(1)  to 2 and  DWORK(2)  to 1, and returns
-C             (see the parameter DWORK).
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the system.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     NSMP    (input) INTEGER
-C             The number of rows of matrices  U  and  Y  (number of
-C             samples,  t).
-C             NSMP >= 0,            if  JOBX0 = 'N'  and  COMUSE <> 'C';
-C             NSMP >= N,            if  JOBX0 = 'X'  and  COMUSE <> 'C';
-C             NSMP >= N*M + a + e,  if  COMUSE = 'C',
-C             where   a = 0,  if  JOBX0 = 'N';
-C                     a = N,  if  JOBX0 = 'X';
-C                     e = 0,  if  JOBX0 = 'X'  and  JOB = 'B';
-C                     e = 1,  if  JOBX0 = 'N'  and  JOB = 'B';
-C                     e = M,  if  JOB   = 'D'.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,N)
-C             If  JOBX0 = 'X'  or  COMUSE = 'C',  the leading N-by-N
-C             part of this array must contain the system state matrix A.
-C             If  N = 0,  or  JOBX0 = 'N'  and  COMUSE <> 'C',  this
-C             array is not referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.
-C             LDA >= MAX(1,N),  if  JOBX0 = 'X'  or   COMUSE =  'C';
-C             LDA >= 1,         if  JOBX0 = 'N'  and  COMUSE <> 'C'.
-C
-C     B       (input or output) DOUBLE PRECISION array, dimension
-C             (LDB,M)
-C             If  JOBX0 = 'X'  and  COMUSE = 'U',  B  is an input
-C             parameter and, on entry, the leading N-by-M part of this
-C             array must contain the system input matrix  B.
-C             If  COMUSE = 'C',  B  is an output parameter and, on exit,
-C             if  INFO = 0,  the leading N-by-M part of this array
-C             contains the estimated system input matrix  B.
-C             If  min(N,M) = 0,  or  JOBX0 = 'N'  and  COMUSE = 'U',
-C             or  COMUSE = 'N',  this array is not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.
-C             LDB >= MAX(1,N),  if  M > 0,  COMUSE = 'U',  JOBX0 = 'X',
-C                               or  M > 0,  COMUSE = 'C';
-C             LDB >= 1,         if  min(N,M) = 0,  or  COMUSE = 'N',
-C                               or  JOBX0  = 'N'  and  COMUSE = 'U'.
-C
-C     C       (input) DOUBLE PRECISION array, dimension (LDC,N)
-C             If  JOBX0 = 'X'  or  COMUSE = 'C',  the leading L-by-N
-C             part of this array must contain the system output
-C             matrix  C.
-C             If  N = 0,  or  JOBX0 = 'N'  and  COMUSE <> 'C',  this
-C             array is not referenced.
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.
-C             LDC >= L,  if  N > 0, and  JOBX0 = 'X'  or  COMUSE = 'C';
-C             LDC >= 1,  if  N = 0, or  JOBX0 = 'N'  and  COMUSE <> 'C'.
-C
-C     D       (input or output) DOUBLE PRECISION array, dimension
-C             (LDD,M)
-C             If  JOBX0 = 'X',  COMUSE = 'U',  and  JOB = 'D',  D  is an
-C             input parameter and, on entry, the leading L-by-M part of
-C             this array must contain the system input-output matrix  D.
-C             If  COMUSE = 'C'  and  JOB = 'D',  D  is an output
-C             parameter and, on exit, if  INFO = 0,  the leading
-C             L-by-M part of this array contains the estimated system
-C             input-output matrix  D.
-C             If  M = 0,  or  JOBX0 = 'N'  and  COMUSE = 'U',  or
-C             COMUSE = 'N',  or  JOB = 'B',  this array is not
-C             referenced.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.
-C             LDD >= L,  if  M > 0,   JOBX0 = 'X',  COMUSE = 'U',  and
-C                                                   JOB = 'D',  or
-C                        if  M > 0,  COMUSE = 'C',  and  JOB = 'D';
-C             LDD >= 1,  if  M = 0,  or  JOBX0 = 'N'  and  COMUSE = 'U',
-C                        or  COMUSE = 'N',  or  JOB = 'B'.
-C
-C     U       (input or input/output) DOUBLE PRECISION array, dimension
-C             (LDU,M)
-C             On entry, if  COMUSE = 'C',  or  JOBX0 = 'X'  and
-C             COMUSE = 'U',  the leading NSMP-by-M part of this array
-C             must contain the t-by-m input-data sequence matrix  U,
-C             U = [u_1 u_2 ... u_m].  Column  j  of  U  contains the
-C             NSMP  values of the j-th input component for consecutive
-C             time increments.
-C             On exit, if  COMUSE = 'C'  and  JOB = 'D',  the leading
-C             NSMP-by-M part of this array contains details of the
-C             QR factorization of the t-by-m matrix  U,  possibly
-C             computed sequentially (see METHOD).
-C             If  COMUSE = 'C'  and  JOB = 'B',  or  COMUSE = 'U',  this
-C             array is unchanged on exit.
-C             If  M = 0,  or  JOBX0 = 'N'  and  COMUSE = 'U',  or
-C             COMUSE = 'N',  this array is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of the array U.
-C             LDU >= MAX(1,NSMP),  if  M > 0    and  COMUSE = 'C'  or
-C                                  JOBX0 = 'X'  and  COMUSE = 'U;
-C             LDU >= 1,            if  M = 0,   or   COMUSE = 'N',  or
-C                                  JOBX0 = 'N'  and  COMUSE = 'U'.
-C
-C     Y       (input) DOUBLE PRECISION array, dimension (LDY,L)
-C             On entry, if  JOBX0 = 'X'  or  COMUSE = 'C',  the leading
-C             NSMP-by-L part of this array must contain the t-by-l
-C             output-data sequence matrix  Y,  Y = [y_1 y_2 ... y_l].
-C             Column  j  of  Y  contains the  NSMP  values of the j-th
-C             output component for consecutive time increments.
-C             If  JOBX0 = 'N'  and  COMUSE <> 'C',  this array is not
-C             referenced.
-C
-C     LDY     INTEGER
-C             The leading dimension of the array Y.
-C             LDY >= MAX(1,NSMP),  if  JOBX0 = 'X'  or   COMUSE = 'C;
-C             LDY >= 1,            if  JOBX0 = 'N'  and  COMUSE <> 'C'.
-C
-C     X0      (output) DOUBLE PRECISION array, dimension (N)
-C             If  INFO = 0  and  JOBX0 = 'X',  this array contains the
-C             estimated initial state of the system,  x(0).
-C             If  JOBX0 = 'N'  and  COMUSE = 'C',  this array is used as
-C             workspace and finally it is set to zero.
-C             If  JOBX0 = 'N'  and  COMUSE = 'U',  then  x(0)  is set to
-C             zero without any calculations.
-C             If  JOBX0 = 'N'  and  COMUSE = 'N',  this array is not
-C             referenced.
-C
-C     V       (output) DOUBLE PRECISION array, dimension (LDV,N)
-C             On exit, if  INFO = 0  or 2,  JOBX0 = 'X'  or
-C             COMUSE = 'C',  the leading N-by-N part of this array
-C             contains the orthogonal matrix V of a real Schur
-C             factorization of the matrix  A.
-C             If  JOBX0 = 'N'  and  COMUSE <> 'C',  this array is not
-C             referenced.
-C
-C     LDV     INTEGER
-C             The leading dimension of the array V.
-C             LDV >= MAX(1,N),  if  JOBX0 = 'X'  or   COMUSE =  'C;
-C             LDV >= 1,         if  JOBX0 = 'N'  and  COMUSE <> 'C'.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used for estimating the rank of
-C             matrices. If the user sets  TOL > 0,  then the given value
-C             of  TOL  is used as a lower bound for the reciprocal
-C             condition number;  a matrix whose estimated condition
-C             number is less than  1/TOL  is considered to be of full
-C             rank.  If the user sets  TOL <= 0,  then  EPS  is used
-C             instead, where  EPS  is the relative machine precision
-C             (see LAPACK Library routine DLAMCH).  TOL <= 1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK), where
-C             LIWORK >= 0,          if  JOBX0 = 'N'  and  COMUSE <> 'C';
-C             LIWORK >= N,          if  JOBX0 = 'X'  and  COMUSE <> 'C';
-C             LIWORK >= N*M + a,        if COMUSE = 'C' and JOB = 'B',
-C             LIWORK >= max(N*M + a,M), if COMUSE = 'C' and JOB = 'D',
-C             with  a = 0,  if  JOBX0 = 'N';
-C                   a = N,  if  JOBX0 = 'X'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of LDWORK;  DWORK(2)  contains the reciprocal condition
-C             number of the triangular factor of the QR factorization of
-C             the matrix  W2,  if  COMUSE = 'C',  or of the matrix
-C             Gamma,  if  COMUSE = 'U'  (see METHOD); if  JOBX0 = 'N'
-C             and  COMUSE <> 'C',  DWORK(2)  is set to one;
-C             if  COMUSE = 'C',  M > 0,  and  JOB = 'D',   DWORK(3)
-C             contains the reciprocal condition number of the triangular
-C             factor of the QR factorization of  U;  denoting
-C                g = 2,  if  JOBX0  = 'X'  and  COMUSE <> 'C'  or
-C                            COMUSE = 'C'  and  M = 0  or   JOB = 'B',
-C                g = 3,  if  COMUSE = 'C'  and  M > 0  and  JOB = 'D',
-C             then  DWORK(i), i = g+1:g+N*N,
-C                   DWORK(j), j = g+1+N*N:g+N*N+L*N,  and
-C                   DWORK(k), k = g+1+N*N+L*N:g+N*N+L*N+N*M,
-C             contain the transformed system matrices  At, Ct, and Bt,
-C             respectively, corresponding to the real Schur form of the
-C             given system state matrix  A,  i.e.,
-C                At = V'*A*V,  Bt = V'*B,  Ct = C*V.
-C             The matrices  At, Ct, Bt  are not computed if  JOBX0 = 'N'
-C             and  COMUSE <> 'C'.
-C             On exit, if  INFO = -26,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 2,  if  JOBX0 = 'N'  and  COMUSE <> 'C',  or
-C                           if  max( N, M ) = 0.
-C             Otherwise,
-C             LDWORK >= LDW1 + N*( N + M + L ) +
-C                              max( 5*N, LDW1, min( LDW2, LDW3 ) ),
-C             where, if  COMUSE = 'C',  then
-C             LDW1 = 2,          if  M = 0  or   JOB = 'B',
-C             LDW1 = 3,          if  M > 0  and  JOB = 'D',
-C             LDWa = t*L*(r + 1) + max( N + max( d, f ), 6*r ),
-C             LDW2 = LDWa,       if  M = 0  or  JOB = 'B',
-C             LDW2 = max( LDWa, t*L*(r + 1) + 2*M*M + 6*M ),
-C                                if  M > 0  and JOB = 'D',
-C             LDWb = (b + r)*(r + 1) +
-C                     max( q*(r + 1) + N*N*M + c + max( d, f ), 6*r ),
-C             LDW3 = LDWb,       if  M = 0  or  JOB = 'B',
-C             LDW3 = max( LDWb, (b + r)*(r + 1) + 2*M*M + 6*M ),
-C                                if  M > 0  and JOB = 'D',
-C                r = N*M + a,
-C                a = 0,                  if  JOBX0 = 'N',
-C                a = N,                  if  JOBX0 = 'X';
-C                b = 0,                  if  JOB   = 'B',
-C                b = L*M,                if  JOB   = 'D';
-C                c = 0,                  if  JOBX0 = 'N',
-C                c = L*N,                if  JOBX0 = 'X';
-C                d = 0,                  if  JOBX0 = 'N',
-C                d = 2*N*N + N,          if  JOBX0 = 'X';
-C                f = 2*r,                if  JOB   = 'B'   or  M = 0,
-C                f = M + max( 2*r, M ),  if  JOB   = 'D'  and  M > 0;
-C                q = b + r*L;
-C             and, if  JOBX0 = 'X'  and  COMUSE <> 'C',  then
-C             LDW1 = 2,
-C             LDW2 = t*L*(N + 1) + 2*N + max( 2*N*N, 4*N ),
-C             LDW3 = N*(N + 1) + 2*N + max( q*(N + 1) + 2*N*N + L*N,
-C                                           4*N ),
-C                q = N*L.
-C             For good performance,  LDWORK  should be larger.
-C             If  LDWORK >= LDW2,  or if  COMUSE = 'C'  and
-C                 LDWORK >= t*L*(r + 1) + (b + r)*(r + 1) + N*N*M + c +
-C                           max( d, f ),
-C             then standard QR factorizations of the matrices  U  and/or
-C             W2,  if  COMUSE = 'C',  or of the matrix  Gamma,  if
-C             JOBX0 = 'X'  and  COMUSE <> 'C'  (see METHOD), are used.
-C             Otherwise, the QR factorizations are computed sequentially
-C             by performing  NCYCLE  cycles, each cycle (except possibly
-C             the last one) processing  s < t  samples, where  s  is
-C             chosen by equating  LDWORK  to the first term of  LDWb,
-C             if  COMUSE = 'C',  or of  LDW3,  if  COMUSE <> 'C',  for
-C             q  replaced by  s*L.  (s  is larger than or equal to the
-C             minimum value of  NSMP.)  The computational effort may
-C             increase and the accuracy may slightly decrease with the
-C             decrease of  s.  Recommended value is  LDWORK = LDW2,
-C             assuming a large enough cache size, to also accommodate
-C             A,  (B,)  C,  (D,)  U,  and  Y.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 4:  the least squares problem to be solved has a
-C                   rank-deficient coefficient matrix;
-C             = 6:  the matrix  A  is unstable;  the estimated  x(0)
-C                   and/or  B and D  could be inaccurate.
-C             NOTE: the value 4 of  IWARN  has no significance for the
-C                   identification problem.
-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 QR algorithm failed to compute all the
-C                   eigenvalues of the matrix A (see LAPACK Library
-C                   routine DGEES); the locations  DWORK(i),  for
-C                   i = g+1:g+N*N,  contain the partially converged
-C                   Schur form;
-C             = 2:  the singular value decomposition (SVD) algorithm did
-C                   not converge.
-C
-C     METHOD
-C
-C     Matrix  A  is initially reduced to a real Schur form, A = V*At*V',
-C     and the given system matrices are transformed accordingly. For the
-C     reduced system, an extension and refinement of the method in [1,2]
-C     is used. Specifically, for  JOBX0 = 'X',  COMUSE = 'C',  and
-C     JOB = 'D',  denoting
-C
-C           X = [ vec(D')' vec(B)' x0' ]',
-C
-C     where  vec(M)  is the vector obtained by stacking the columns of
-C     the matrix  M,  then  X  is the least squares solution of the
-C     system  S*X = vec(Y),  with the matrix  S = [ diag(U)  W ],
-C     defined by
-C
-C           ( U         |     | ... |     |     | ... |     |         )
-C           (   U       |  11 | ... |  n1 |  12 | ... |  nm |         )
-C       S = (     :     | y   | ... | y   | y   | ... | y   | P*Gamma ),
-C           (       :   |     | ... |     |     | ... |     |         )
-C           (         U |     | ... |     |     | ... |     |         )
-C                                                                     ij
-C     diag(U)  having  L  block rows and columns.  In this formula,  y
-C     are the outputs of the system for zero initial state computed
-C     using the following model, for j = 1:m, and for i = 1:n,
-C            ij          ij                    ij
-C           x  (k+1) = Ax  (k) + e_i u_j(k),  x  (0) = 0,
-C
-C            ij          ij
-C           y  (k)   = Cx  (k),
-C
-C     where  e_i  is the i-th n-dimensional unit vector,  Gamma  is
-C     given by
-C
-C                (     C     )
-C                (    C*A    )
-C        Gamma = (   C*A^2   ),
-C                (     :     )
-C                ( C*A^(t-1) )
-C
-C     and  P  is a permutation matrix that groups together the rows of
-C     Gamma  depending on the same row of  C,  namely
-C     [ c_j;  c_j*A;  c_j*A^2; ...  c_j*A^(t-1) ],  for j = 1:L.
-C     The first block column,  diag(U),  is not explicitly constructed,
-C     but its structure is exploited. The last block column is evaluated
-C     using powers of A with exponents 2^k. No interchanges are applied.
-C     A special QR decomposition of the matrix  S  is computed. Let
-C     U = q*[ r' 0 ]'  be the QR decomposition of  U,  if  M > 0,  where
-C     r  is  M-by-M.   Then,  diag(q')  is applied to  W  and  vec(Y).
-C     The block-rows of  S  and  vec(Y)  are implicitly permuted so that
-C     matrix  S  becomes
-C
-C        ( diag(r)  W1 )
-C        (    0     W2 ),
-C
-C     where  W1  has L*M rows. Then, the QR decomposition of  W2 is
-C     computed (sequentially, if  M > 0) and used to obtain  B  and  x0.
-C     The intermediate results and the QR decomposition of  U  are
-C     needed to find  D.  If a triangular factor is too ill conditioned,
-C     then singular value decomposition (SVD) is employed. SVD is not
-C     generally needed if the input sequence is sufficiently
-C     persistently exciting and  NSMP  is large enough.
-C     If the matrix  W  cannot be stored in the workspace (i.e.,
-C     LDWORK < LDW2),  the QR decompositions of  W2  and  U  are
-C     computed sequentially.
-C     For  JOBX0 = 'N'  and  COMUSE = 'C',  or  JOB = 'B',  a simpler
-C     problem is solved efficiently.
-C
-C     For  JOBX0 = 'X'  and  COMUSE <> 'C',  a simpler method is used.
-C     Specifically, the output y0(k) of the system for zero initial
-C     state is computed for k = 0, 1, ...,  t-1 using the given model.
-C     Then the following least squares problem is solved for x(0)
-C
-C                         (   y(0) - y0(0)   )
-C                         (   y(1) - y0(1)   )
-C        Gamma * x(0)  =  (        :         ).
-C                         (        :         )
-C                         ( y(t-1) - y0(t-1) )
-C
-C     The coefficient matrix  Gamma  is evaluated using powers of A with
-C     exponents 2^k. The QR decomposition of this matrix is computed.
-C     If its triangular factor  R  is too ill conditioned, then singular
-C     value decomposition of  R  is used.
-C     If the coefficient matrix cannot be stored in the workspace (i.e.,
-C     LDWORK < LDW2),  the QR decomposition is computed sequentially.
-C
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Varga, A.
-C         Some Experience with the MOESP Class of Subspace Model
-C         Identification Methods in Identifying the BO105 Helicopter.
-C         Report TR R165-94, DLR Oberpfaffenhofen, 1994.
-C
-C     [2] Sima, V., and Varga, A.
-C         RASP-IDENT : Subspace Model Identification Programs.
-C         Deutsche Forschungsanstalt fur Luft- und Raumfahrt e. V.,
-C         Report TR R888-94, DLR Oberpfaffenhofen, Oct. 1994.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is numerically stable.
-C
-C     FURTHER COMMENTS
-C
-C     The algorithm for computing the system matrices  B  and  D  is
-C     less efficient than the MOESP or N4SID algorithms implemented in
-C     SLICOT Library routines IB01BD/IB01PD, because a large least
-C     squares problem has to be solved, but the accuracy is better, as
-C     the computed matrices  B  and  D  are fitted to the input and
-C     output trajectories. However, if matrix  A  is unstable, the
-C     computed matrices  B  and  D  could be inaccurate.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 2000.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Identification methods; least squares solutions; multivariable
-C     systems; QR decomposition; singular value decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, THREE
-      PARAMETER          ( ZERO  = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
-     $                     THREE = 3.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   TOL
-      INTEGER            INFO, IWARN, L, LDA, LDB, LDC, LDD, LDU, LDV,
-     $                   LDWORK, LDY, M, N, NSMP
-      CHARACTER          COMUSE, JOB, JOBX0
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA, *), B(LDB, *), C(LDC, *), D(LDD, *),
-     $                   DWORK(*),  U(LDU, *), V(LDV, *), X0(*),
-     $                   Y(LDY, *)
-      INTEGER            IWORK(*)
-C     .. Local Scalars ..
-      DOUBLE PRECISION   RCOND, RCONDU
-      INTEGER            I, IA, IB, IC, IERR, IQ, ISIZE, ITAU, IWARNL,
-     $                   IWI, IWR, JWORK, LDW, LDW2, LDW3, LM, LN,
-     $                   MAXWRK, MINSMP, MINWLS, MINWRK, MTMP, N2M,
-     $                   NCOL, NCP1, NM, NN, NSMPL
-      LOGICAL            COMPBD, USEBD, MAXDIA, MAXDIM, WITHB, WITHD,
-     $                   WITHX0
-      CHARACTER          JOBD
-C     .. Local Arrays ..
-      DOUBLE PRECISION   DUM(1)
-C     .. External Functions ..
-      LOGICAL            LSAME
-      INTEGER            ILAENV
-      DOUBLE PRECISION   DLAMCH, DLAPY2
-      EXTERNAL           DLAMCH, DLAPY2, ILAENV, LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DCOPY, DGEMM, DGEMV, DLACPY, IB01QD, IB01RD,
-     $                   TB01WD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          INT, MAX, MIN
-C     .. Executable Statements ..
-C
-C     Check the input parameters.
-C
-      WITHX0 = LSAME( JOBX0,  'X' )
-      COMPBD = LSAME( COMUSE, 'C' )
-      USEBD  = LSAME( COMUSE, 'U' )
-      WITHD  = LSAME( JOB,    'D' )
-      WITHB  = LSAME( JOB,    'B' )   .OR. WITHD
-      MAXDIM = ( WITHX0 .AND. USEBD ) .OR. COMPBD
-      MAXDIA = WITHX0 .OR. COMPBD
-C
-      IWARN = 0
-      INFO  = 0
-      LDW   = MAX( 1, N )
-      LM    = L*M
-      LN    = L*N
-      NN    = N*N
-      NM    = N*M
-      N2M   = N*NM
-      IF( COMPBD ) THEN
-         NCOL = NM
-         IF( WITHX0 )
-     $      NCOL = NCOL + N
-         MINSMP = NCOL
-         IF( WITHD ) THEN
-            MINSMP = MINSMP + M
-            IQ     = MINSMP
-         ELSE IF ( .NOT.WITHX0 ) THEN
-            IQ     = MINSMP
-            MINSMP = MINSMP + 1
-         ELSE
-            IQ     = MINSMP
-         END IF
-      ELSE
-         NCOL = N
-         IF( WITHX0 ) THEN
-            MINSMP = N
-         ELSE
-            MINSMP = 0
-         END IF
-         IQ = MINSMP
-      END IF
-C
-      IF( .NOT.( WITHX0 .OR. LSAME( JOBX0, 'N' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( COMPBD .OR. USEBD .OR. LSAME( COMUSE, 'N' ) ) )
-     $      THEN
-         INFO = -2
-      ELSE IF( .NOT.WITHB ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( L.LE.0 ) THEN
-         INFO = -6
-      ELSE IF( NSMP.LT.MINSMP ) THEN
-         INFO = -7
-      ELSE IF( LDA.LT.1 .OR. ( MAXDIA .AND. LDA.LT.LDW ) ) THEN
-         INFO = -9
-      ELSE IF( LDB.LT.1 .OR. ( M.GT.0 .AND. MAXDIM .AND. LDB.LT.LDW ) )
-     $      THEN
-         INFO = -11
-      ELSE IF( LDC.LT.1 .OR. ( N.GT.0 .AND. MAXDIA .AND. LDC.LT.L ) )
-     $      THEN
-         INFO = -13
-      ELSE IF( LDD.LT.1 .OR. ( M.GT.0 .AND. MAXDIM .AND. WITHD .AND.
-     $         LDD.LT.L ) ) THEN
-         INFO = -15
-      ELSE IF( LDU.LT.1 .OR. ( M.GT.0 .AND. MAXDIM .AND. LDU.LT.NSMP ) )
-     $      THEN
-         INFO = -17
-      ELSE IF( LDY.LT.1 .OR. ( MAXDIA .AND. LDY.LT.NSMP ) ) THEN
-         INFO = -19
-      ELSE IF( LDV.LT.1 .OR. ( MAXDIA .AND. LDV.LT.LDW ) ) THEN
-         INFO = -22
-      ELSE IF( TOL.GT.ONE ) THEN
-         INFO = -23
-      END IF
-C
-C     Compute workspace.
-C      (Note: Comments in the code beginning "Workspace:" describe the
-C       minimal amount of workspace needed at that point in the code,
-C       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 ( .NOT.MAXDIA .OR. MAX( N, M ).EQ.0 ) THEN
-         MINWRK = 2
-      ELSE
-         NSMPL = NSMP*L
-         IQ    = IQ*L
-         NCP1  = NCOL + 1
-         ISIZE = NSMPL*NCP1
-         IF ( COMPBD ) THEN
-            IF ( N.GT.0 .AND. WITHX0 ) THEN
-               IC = 2*NN + N
-            ELSE
-               IC = 0
-            END IF
-         ELSE
-            IC = 2*NN
-         END IF
-         MINWLS = NCOL*NCP1
-         IF ( COMPBD ) THEN
-            IF ( WITHD )
-     $         MINWLS = MINWLS + LM*NCP1
-            IF ( M.GT.0 .AND. WITHD ) THEN
-               IA = M + MAX( 2*NCOL, M )
-            ELSE
-               IA = 2*NCOL
-            END IF
-            ITAU = N2M + MAX( IC, IA )
-            IF ( WITHX0 )
-     $         ITAU = ITAU + LN
-            LDW2 = ISIZE  + MAX( N + MAX( IC, IA ), 6*NCOL )
-            LDW3 = MINWLS + MAX( IQ*NCP1 + ITAU, 6*NCOL )
-            IF ( M.GT.0 .AND. WITHD ) THEN
-               LDW2 = MAX( LDW2, ISIZE  + 2*M*M + 6*M )
-               LDW3 = MAX( LDW3, MINWLS + 2*M*M + 6*M )
-               IA   = 3
-            ELSE
-               IA = 2
-            END IF
-         ELSE
-            ITAU = IC + LN
-            LDW2 = ISIZE  + 2*N + MAX( IC, 4*N )
-            LDW3 = MINWLS + 2*N + MAX( IQ*NCP1 + ITAU, 4*N )
-            IA   = 2
-         END IF
-         MINWRK = IA + NN + NM + LN + MAX( 5*N, IA, MIN( LDW2, LDW3 ) )
-C
-         IF ( INFO.EQ.0 .AND. LDWORK.GE.MINWRK ) THEN
-            MAXWRK = MAX( 5*N, IA )
-            IF ( COMPBD ) THEN
-               IF ( M.GT.0 .AND. WITHD ) THEN
-                  MAXWRK = MAX( MAXWRK, ISIZE + N + M +
-     $                          MAX( M*ILAENV( 1, 'DGEQRF', ' ', NSMP,
-     $                                         M, -1, -1 ),
-     $                               NCOL + NCOL*ILAENV( 1, 'DGEQRF',
-     $                                   ' ', NSMP-M, NCOL, -1, -1 ) ) )
-                  MAXWRK = MAX( MAXWRK, ISIZE + N + M +
-     $                          MAX( NCP1*ILAENV( 1, 'DORMQR', 'LT',
-     $                                            NSMP, NCP1, M, -1 ),
-     $                               NCOL + ILAENV( 1, 'DORMQR', 'LT',
-     $                                         NSMP-M, 1, NCOL, -1 ) ) )
-               ELSE
-                  MAXWRK = MAX( MAXWRK, ISIZE + N + NCOL +
-     $                                  MAX( NCOL*ILAENV( 1, 'DGEQRF',
-     $                                       ' ', NSMPL, NCOL, -1, -1 ),
-     $                                       ILAENV( 1, 'DORMQR', 'LT',
-     $                                          NSMPL, 1, NCOL, -1 ) ) )
-               END IF
-            ELSE
-               MAXWRK = MAX( MAXWRK, ISIZE + 2*N +
-     $                               MAX( N*ILAENV( 1, 'DGEQRF', ' ',
-     $                                              NSMPL, N, -1, -1 ),
-     $                                    ILAENV( 1, 'DORMQR', 'LT',
-     $                                            NSMPL, 1, N, -1 ) ) )
-            END IF
-            MAXWRK = IA + NN + NM + LN + MAXWRK
-            MAXWRK = MAX( MAXWRK, MINWRK )
-         END IF
-      END IF
-C
-      IF ( INFO.EQ.0 .AND. LDWORK.LT.MINWRK ) THEN
-         INFO = -26
-         DWORK(1) = MINWRK
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01CD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( .NOT.MAXDIA .OR. MAX( N, M ).EQ.0 ) THEN
-         DWORK(2) = ONE
-         IF ( COMPBD .AND. M.GT.0 .AND. WITHD ) THEN
-            DWORK(1) = THREE
-            DWORK(3) = ONE
-         ELSE
-            DWORK(1) = TWO
-         END IF
-         IF ( N.GT.0 .AND. USEBD ) THEN
-            DUM(1) = ZERO
-            CALL DCOPY( N, DUM, 0, X0, 1 )
-         END IF
-         RETURN
-      END IF
-C
-C     Compute the Schur factorization of  A  and transform the other
-C     given system matrices accordingly.
-C     Workspace:  need   g + N*N + L*N + N*M + 5*N,  where
-C                        g = 2,  if  M = 0, COMUSE = 'C', or  JOB = 'B',
-C                        g = 3,  if  M > 0, COMUSE = 'C', and JOB = 'D',
-C                        g = 2,  if  JOBX0 = 'X'  and  COMUSE <> 'C';
-C                 prefer larger.
-C
-      IA = IA + 1
-      IC = IA + NN
-      IB = IC + LN
-      CALL DLACPY( 'Full', N, N, A, LDA, DWORK(IA), LDW )
-      CALL DLACPY( 'Full', L, N, C, LDC, DWORK(IC), L )
-C
-      IF ( USEBD ) THEN
-         MTMP = M
-         CALL DLACPY( 'Full', N, M, B, LDB, DWORK(IB), LDW )
-      ELSE
-         MTMP = 0
-      END IF
-      IWR   = IB  + NM
-      IWI   = IWR + N
-      JWORK = IWI + N
-C
-      CALL TB01WD( N, MTMP, L, DWORK(IA), LDW, DWORK(IB), LDW,
-     $             DWORK(IC), L, V, LDV, DWORK(IWR), DWORK(IWI),
-     $             DWORK(JWORK), LDWORK-JWORK+1, IERR )
-      IF( IERR.GT.0 ) THEN
-         INFO = 1
-         RETURN
-      END IF
-      MAXWRK = MAX( MAXWRK, INT( DWORK( JWORK ) ) + JWORK - 1 )
-C
-      DO 10 I = IWR, IWI - 1
-         IF( DLAPY2( DWORK(I), DWORK(I+N) ).GE.ONE )
-     $      IWARN = 6
-   10 CONTINUE
-C
-      JWORK = IWR
-C
-C     Estimate  x(0)  and/or the system matrices  B and D.
-C     Workspace: need   g + N*N + L*N + N*M +
-C                           max( g, min( LDW2, LDW3 ) ) (see LDWORK);
-C                prefer larger.
-C
-      IF ( COMPBD ) THEN
-         CALL IB01QD( JOBX0, JOB, N, M, L, NSMP, DWORK(IA), LDW,
-     $                DWORK(IC), L, U, LDU, Y, LDY, X0, DWORK(IB), LDW,
-     $                D, LDD, TOL, IWORK, DWORK(JWORK), LDWORK-JWORK+1,
-     $                IWARNL, INFO )
-C
-         IF( INFO.EQ.0 ) THEN
-            IF ( M.GT.0 .AND. WITHD )
-     $         RCONDU = DWORK(JWORK+2)
-C
-C           Compute the system input matrix  B  corresponding to the
-C           original system.
-C
-            CALL DGEMM( 'NoTranspose', 'NoTranspose', N, M, N, ONE,
-     $                  V, LDV, DWORK(IB), LDW, ZERO, B, LDB )
-         END IF
-      ELSE
-         IF ( WITHD ) THEN
-            JOBD = 'N'
-         ELSE
-            JOBD = 'Z'
-         END IF
-C
-         CALL IB01RD( JOBD, N, MTMP, L, NSMP, DWORK(IA), LDW, DWORK(IB),
-     $                LDW, DWORK(IC), L, D, LDD, U, LDU, Y, LDY, X0,
-     $                TOL, IWORK, DWORK(JWORK), LDWORK-JWORK+1, IWARNL,
-     $                INFO )
-      END IF
-      IWARN = MAX( IWARN, IWARNL )
-C
-      IF( INFO.EQ.0 ) THEN
-         RCOND  = DWORK(JWORK+1)
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-         IF( WITHX0 ) THEN
-C
-C           Transform the initial state estimate to obtain the initial
-C           state corresponding to the original system.
-C           Workspace: need g + N*N + L*N + N*M + N.
-C
-            CALL DGEMV( 'NoTranspose', N, N, ONE, V, LDV, X0, 1, ZERO,
-     $                  DWORK(JWORK), 1 )
-            CALL DCOPY( N, DWORK(JWORK), 1, X0, 1 )
-         END IF
-C
-         DWORK(1) = MAXWRK
-         DWORK(2) = RCOND
-         IF ( COMPBD .AND. M.GT.0 .AND. WITHD )
-     $      DWORK(3) = RCONDU
-      END IF
-      RETURN
-C
-C *** End of IB01CD ***
-      END
--- a/extra/control-devel/src/IB01MD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1433 +0,0 @@
-      SUBROUTINE IB01MD( METH, ALG, BATCH, CONCT, NOBR, M, L, NSMP, U,
-     $                   LDU, Y, LDY, R, LDR, IWORK, DWORK, LDWORK,
-     $                   IWARN, 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 an upper triangular factor  R  of the concatenated
-C     block Hankel matrices using input-output data.  The input-output
-C     data can, optionally, be processed sequentially.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     METH    CHARACTER*1
-C             Specifies the subspace identification method to be used,
-C             as follows:
-C             = 'M':  MOESP  algorithm with past inputs and outputs;
-C             = 'N':  N4SID  algorithm.
-C
-C     ALG     CHARACTER*1
-C             Specifies the algorithm for computing the triangular
-C             factor R, as follows:
-C             = 'C':  Cholesky algorithm applied to the correlation
-C                     matrix of the input-output data;
-C             = 'F':  Fast QR algorithm;
-C             = 'Q':  QR algorithm applied to the concatenated block
-C                     Hankel matrices.
-C
-C     BATCH   CHARACTER*1
-C             Specifies whether or not sequential data processing is to
-C             be used, and, for sequential processing, whether or not
-C             the current data block is the first block, an intermediate
-C             block, or the last block, as follows:
-C             = 'F':  the first block in sequential data processing;
-C             = 'I':  an intermediate block in sequential data
-C                     processing;
-C             = 'L':  the last block in sequential data processing;
-C             = 'O':  one block only (non-sequential data processing).
-C             NOTE that when  100  cycles of sequential data processing
-C                  are completed for  BATCH = 'I',  a warning is
-C                  issued, to prevent for an infinite loop.
-C
-C     CONCT   CHARACTER*1
-C             Specifies whether or not the successive data blocks in
-C             sequential data processing belong to a single experiment,
-C             as follows:
-C             = 'C':  the current data block is a continuation of the
-C                     previous data block and/or it will be continued
-C                     by the next data block;
-C             = 'N':  there is no connection between the current data
-C                     block and the previous and/or the next ones.
-C             This parameter is not used if BATCH = 'O'.
-C
-C     Input/Output Parameters
-C
-C     NOBR    (input) INTEGER
-C             The number of block rows,  s,  in the input and output
-C             block Hankel matrices to be processed.  NOBR > 0.
-C             (In the MOESP theory,  NOBR  should be larger than  n,
-C             the estimated dimension of state vector.)
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C             When M = 0, no system inputs are processed.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     NSMP    (input) INTEGER
-C             The number of rows of matrices  U  and  Y  (number of
-C             samples,  t). (When sequential data processing is used,
-C             NSMP  is the number of samples of the current data
-C             block.)
-C             NSMP >= 2*(M+L+1)*NOBR - 1,  for non-sequential
-C                                          processing;
-C             NSMP >= 2*NOBR,  for sequential processing.
-C             The total number of samples when calling the routine with
-C             BATCH = 'L'  should be at least  2*(M+L+1)*NOBR - 1.
-C             The  NSMP  argument may vary from a cycle to another in
-C             sequential data processing, but  NOBR, M,  and  L  should
-C             be kept constant. For efficiency, it is advisable to use
-C             NSMP  as large as possible.
-C
-C     U       (input) DOUBLE PRECISION array, dimension (LDU,M)
-C             The leading NSMP-by-M part of this array must contain the
-C             t-by-m input-data sequence matrix  U,
-C             U = [u_1 u_2 ... u_m].  Column  j  of  U  contains the
-C             NSMP  values of the j-th input component for consecutive
-C             time increments.
-C             If M = 0, this array is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of the array U.
-C             LDU >= NSMP, if M > 0;
-C             LDU >= 1,    if M = 0.
-C
-C     Y       (input) DOUBLE PRECISION array, dimension (LDY,L)
-C             The leading NSMP-by-L part of this array must contain the
-C             t-by-l output-data sequence matrix  Y,
-C             Y = [y_1 y_2 ... y_l].  Column  j  of  Y  contains the
-C             NSMP  values of the j-th output component for consecutive
-C             time increments.
-C
-C     LDY     INTEGER
-C             The leading dimension of the array Y.  LDY >= NSMP.
-C
-C     R       (output or input/output) DOUBLE PRECISION array, dimension
-C             ( LDR,2*(M+L)*NOBR )
-C             On exit, if INFO = 0 and ALG = 'Q', or (ALG = 'C' or 'F',
-C             and BATCH = 'L' or 'O'), the leading
-C             2*(M+L)*NOBR-by-2*(M+L)*NOBR upper triangular part of
-C             this array contains the (current) upper triangular factor
-C             R from the QR factorization of the concatenated block
-C             Hankel matrices. The diagonal elements of R are positive
-C             when the Cholesky algorithm was successfully used.
-C             On exit, if ALG = 'C' and BATCH = 'F' or 'I', the leading
-C             2*(M+L)*NOBR-by-2*(M+L)*NOBR upper triangular part of this
-C             array contains the current upper triangular part of the
-C             correlation matrix in sequential data processing.
-C             If ALG = 'F' and BATCH = 'F' or 'I', the array R is not
-C             referenced.
-C             On entry, if ALG = 'C', or ALG = 'Q', and BATCH = 'I' or
-C             'L', the leading  2*(M+L)*NOBR-by-2*(M+L)*NOBR  upper
-C             triangular part of this array must contain the upper
-C             triangular matrix R computed at the previous call of this
-C             routine in sequential data processing. The array R need
-C             not be set on entry if ALG = 'F' or if BATCH = 'F' or 'O'.
-C
-C     LDR     INTEGER
-C             The leading dimension of the array  R.
-C             LDR >= 2*(M+L)*NOBR.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK >= M+L, if ALG = 'F';
-C             LIWORK >= 0,   if ALG = 'C' or 'Q'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if  INFO = 0,  DWORK(1)  returns the optimal
-C             value of LDWORK.
-C             On exit, if  INFO = -17,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C             Let
-C             k = 0,               if CONCT = 'N' and ALG = 'C' or 'Q';
-C             k = 2*NOBR-1,        if CONCT = 'C' and ALG = 'C' or 'Q';
-C             k = 2*NOBR*(M+L+1),  if CONCT = 'N' and ALG = 'F';
-C             k = 2*NOBR*(M+L+2),  if CONCT = 'C' and ALG = 'F'.
-C             The first (M+L)*k elements of  DWORK  should be preserved
-C             during successive calls of the routine with  BATCH = 'F'
-C             or  'I',  till the final call with  BATCH = 'L'.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= (4*NOBR-2)*(M+L), if ALG = 'C', BATCH <> 'O' and
-C                                     CONCT = 'C';
-C             LDWORK >= 1,            if ALG = 'C', BATCH = 'O' or
-C                                     CONCT = 'N';
-C             LDWORK >= (M+L)*2*NOBR*(M+L+3), if ALG = 'F',
-C                                     BATCH <> 'O' and CONCT = 'C';
-C             LDWORK >= (M+L)*2*NOBR*(M+L+1), if ALG = 'F',
-C                                     BATCH = 'F', 'I' and CONCT = 'N';
-C             LDWORK >= (M+L)*4*NOBR*(M+L+1)+(M+L)*2*NOBR, if ALG = 'F',
-C                                     BATCH = 'L' and CONCT = 'N', or
-C                                     BATCH = 'O';
-C             LDWORK >= 4*(M+L)*NOBR, if ALG = 'Q', BATCH = 'F' or 'O',
-C                                     and LDR >= NS = NSMP - 2*NOBR + 1;
-C             LDWORK >= 6*(M+L)*NOBR, if ALG = 'Q', BATCH = 'F' or 'O',
-C                                     and LDR < NS, or BATCH = 'I' or
-C                                     'L' and CONCT = 'N';
-C             LDWORK >= 4*(NOBR+1)*(M+L)*NOBR, if ALG = 'Q', BATCH = 'I'
-C                                     or 'L' and CONCT = 'C'.
-C             The workspace used for ALG = 'Q' is
-C                       LDRWRK*2*(M+L)*NOBR + 4*(M+L)*NOBR,
-C             where LDRWRK = LDWORK/(2*(M+L)*NOBR) - 2; recommended
-C             value LDRWRK = NS, assuming a large enough cache size.
-C             For good performance,  LDWORK  should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  the number of 100 cycles in sequential data
-C                   processing has been exhausted without signaling
-C                   that the last block of data was get; the cycle
-C                   counter was reinitialized;
-C             = 2:  a fast algorithm was requested (ALG = 'C' or 'F'),
-C                   but it failed, and the QR algorithm was then used
-C                   (non-sequential data processing).
-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:  a fast algorithm was requested (ALG = 'C', or 'F')
-C                   in sequential data processing, but it failed. The
-C                   routine can be repeatedly called again using the
-C                   standard QR algorithm.
-C
-C     METHOD
-C
-C     1) For non-sequential data processing using QR algorithm, a
-C     t x 2(m+l)s  matrix H is constructed, where
-C
-C          H = [ Uf'         Up'      Y'      ],  for METH = 'M',
-C                  s+1,2s,t    1,s,t   1,2s,t
-C
-C          H = [ U'       Y'      ],              for METH = 'N',
-C                 1,2s,t   1,2s,t
-C
-C     and  Up     , Uf        , U      , and  Y        are block Hankel
-C            1,s,t    s+1,2s,t   1,2s,t        1,2s,t
-C     matrices defined in terms of the input and output data [3].
-C     A QR factorization is used to compress the data.
-C     The fast QR algorithm uses a QR factorization which exploits
-C     the block-Hankel structure. Actually, the Cholesky factor of H'*H
-C     is computed.
-C
-C     2) For sequential data processing using QR algorithm, the QR
-C     decomposition is done sequentially, by updating the upper
-C     triangular factor  R.  This is also performed internally if the
-C     workspace is not large enough to accommodate an entire batch.
-C
-C     3) For non-sequential or sequential data processing using
-C     Cholesky algorithm, the correlation matrix of input-output data is
-C     computed (sequentially, if requested), taking advantage of the
-C     block Hankel structure [7].  Then, the Cholesky factor of the
-C     correlation matrix is found, if possible.
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Dewilde, P.
-C         Subspace Model Identification. Part 1: The output-error
-C         state-space model identification class of algorithms.
-C         Int. J. Control, 56, pp. 1187-1210, 1992.
-C
-C     [2] Verhaegen M.
-C         Subspace Model Identification. Part 3: Analysis of the
-C         ordinary output-error state-space model identification
-C         algorithm.
-C         Int. J. Control, 58, pp. 555-586, 1993.
-C
-C     [3] Verhaegen M.
-C         Identification of the deterministic part of MIMO state space
-C         models given in innovations form from input-output data.
-C         Automatica, Vol.30, No.1, pp.61-74, 1994.
-C
-C     [4] Van Overschee, P., and De Moor, B.
-C         N4SID: Subspace Algorithms for the Identification of
-C         Combined Deterministic-Stochastic Systems.
-C         Automatica, Vol.30, No.1, pp. 75-93, 1994.
-C
-C     [5] Peternell, K., Scherrer, W. and Deistler, M.
-C         Statistical Analysis of Novel Subspace Identification Methods.
-C         Signal Processing, 52, pp. 161-177, 1996.
-C
-C     [6] Sima, V.
-C         Subspace-based Algorithms for Multivariable System
-C         Identification.
-C         Studies in Informatics and Control, 5, pp. 335-344, 1996.
-C
-C     [7] Sima, V.
-C         Cholesky or QR Factorization for Data Compression in
-C         Subspace-based Identification ?
-C         Proceedings of the Second NICONET Workshop on ``Numerical
-C         Control Software: SLICOT, a Useful Tool in Industry'',
-C         December 3, 1999, INRIA Rocquencourt, France, pp. 75-80, 1999.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is numerically stable (when QR algorithm is
-C     used), reliable and efficient. The fast Cholesky or QR algorithms
-C     are more efficient, but the accuracy could diminish by forming the
-C     correlation matrix.
-C                                        2
-C     The QR algorithm needs 0(t(2(m+l)s) ) floating point operations.
-C                                           2              3
-C     The Cholesky algorithm needs 0(2t(m+l) s)+0((2(m+l)s) ) floating
-C     point operations.
-C                                          2           3 2
-C     The fast QR algorithm needs 0(2t(m+l) s)+0(4(m+l) s ) floating
-C     point operations.
-C
-C     FURTHER COMMENTS
-C
-C     For ALG = 'Q', BATCH = 'O' and LDR < NS, or BATCH <> 'O', the
-C     calculations could be rather inefficient if only minimal workspace
-C     (see argument LDWORK) is provided. It is advisable to provide as
-C     much workspace as possible. Almost optimal efficiency can be
-C     obtained for  LDWORK = (NS+2)*(2*(M+L)*NOBR),  assuming that the
-C     cache size is large enough to accommodate R, U, Y, and DWORK.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 1999.
-C
-C     REVISIONS
-C
-C     Feb. 2000, Aug. 2000, Feb. 2004.
-C
-C     KEYWORDS
-C
-C     Cholesky decomposition, Hankel matrix, identification methods,
-C     multivariable systems, QR decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
-      INTEGER            MAXCYC
-      PARAMETER          ( MAXCYC = 100 )
-C     .. Scalar Arguments ..
-      INTEGER            INFO, IWARN, L, LDR, LDU, LDWORK, LDY, M, NOBR,
-     $                   NSMP
-      CHARACTER          ALG, BATCH, CONCT, METH
-C     .. Array Arguments ..
-      INTEGER            IWORK(*)
-      DOUBLE PRECISION   DWORK(*), R(LDR, *), U(LDU, *), Y(LDY, *)
-C     .. Local Scalars ..
-      DOUBLE PRECISION   UPD, TEMP
-      INTEGER            I, ICOL, ICYCLE, ID, IERR, II, INICYC, INIT,
-     $                   INITI, INU, INY, IREV, ISHFT2, ISHFTU, ISHFTY,
-     $                   ITAU, J, JD, JWORK, LDRWMX, LDRWRK, LLDRW,
-     $                   LMNOBR, LNOBR, MAXWRK, MINWRK, MLDRW, MMNOBR,
-     $                   MNOBR, NCYCLE, NICYCL, NOBR2, NOBR21, NOBRM1,
-     $                   NR, NS, NSF, NSL, NSLAST, NSMPSM
-      LOGICAL            CHALG, CONNEC, FIRST, FQRALG, INTERM, LAST,
-     $                   LINR, MOESP, N4SID, ONEBCH, QRALG
-C     .. Local Arrays ..
-      DOUBLE PRECISION   DUM( 1 )
-C     .. External Functions ..
-      LOGICAL            LSAME
-      INTEGER            ILAENV
-      EXTERNAL           ILAENV, LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DAXPY, DCOPY, DGEMM, DGEQRF, DGER, DLACPY,
-     $                   DLASET, DPOTRF, DSWAP, DSYRK, IB01MY, MB04OD,
-     $                   XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          INT, MAX, MIN
-C     .. Save Statement ..
-C        ICYCLE  is used to count the cycles for  BATCH = 'I'. It is
-C                reinitialized at each MAXCYC cycles.
-C        MAXWRK  is used to store the optimal workspace.
-C        NSMPSM  is used to sum up the  NSMP  values for  BATCH <> 'O'.
-      SAVE               ICYCLE, MAXWRK, NSMPSM
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode the scalar input parameters.
-C
-      MOESP  = LSAME( METH,  'M' )
-      N4SID  = LSAME( METH,  'N' )
-      FQRALG = LSAME( ALG,   'F' )
-      QRALG  = LSAME( ALG,   'Q' )
-      CHALG  = LSAME( ALG,   'C' )
-      ONEBCH = LSAME( BATCH, 'O' )
-      FIRST  = LSAME( BATCH, 'F' ) .OR. ONEBCH
-      INTERM = LSAME( BATCH, 'I' )
-      LAST   = LSAME( BATCH, 'L' ) .OR. ONEBCH
-      IF( .NOT.ONEBCH ) THEN
-         CONNEC = LSAME( CONCT, 'C' )
-      ELSE
-         CONNEC = .FALSE.
-      END IF
-C
-      MNOBR  = M*NOBR
-      LNOBR  = L*NOBR
-      LMNOBR = LNOBR + MNOBR
-      MMNOBR = MNOBR + MNOBR
-      NOBRM1 = NOBR - 1
-      NOBR21 = NOBR + NOBRM1
-      NOBR2  = NOBR21 + 1
-      IWARN  = 0
-      INFO   = 0
-      IERR   = 0
-      IF( FIRST ) THEN
-         ICYCLE = 1
-         MAXWRK = 1
-         NSMPSM = 0
-      END IF
-      NSMPSM = NSMPSM + NSMP
-      NR = LMNOBR + LMNOBR
-C
-C     Check the scalar input parameters.
-C
-      IF( .NOT.( MOESP .OR. N4SID ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( FQRALG .OR. QRALG .OR. CHALG ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.( FIRST .OR. INTERM .OR. LAST ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT. ONEBCH ) THEN
-         IF( .NOT.( CONNEC .OR. LSAME( CONCT, 'N' ) ) )
-     $      INFO = -4
-      END IF
-      IF( INFO.EQ.0 ) THEN
-         IF( NOBR.LE.0 ) THEN
-            INFO = -5
-         ELSE IF( M.LT.0 ) THEN
-            INFO = -6
-         ELSE IF( L.LE.0 ) THEN
-            INFO = -7
-         ELSE IF( NSMP.LT.NOBR2 .OR.
-     $          ( LAST .AND. NSMPSM.LT.NR+NOBR21 ) ) THEN
-            INFO = -8
-         ELSE IF( LDU.LT.1 .OR. ( M.GT.0 .AND. LDU.LT.NSMP ) ) THEN
-            INFO = -10
-         ELSE IF( LDY.LT.NSMP ) THEN
-            INFO = -12
-         ELSE IF( LDR.LT.NR ) THEN
-            INFO = -14
-         ELSE
-C
-C           Compute workspace.
-C           (Note: Comments in the code beginning "Workspace:" describe
-C           the minimal amount of 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
-            NS = NSMP - NOBR21
-            IF ( CHALG ) THEN
-               IF ( .NOT.ONEBCH .AND. CONNEC ) THEN
-                  MINWRK = 2*( NR - M - L )
-               ELSE
-                  MINWRK = 1
-               END IF
-            ELSE IF ( FQRALG ) THEN
-               IF ( .NOT.ONEBCH .AND. CONNEC ) THEN
-                  MINWRK = NR*( M + L + 3 )
-               ELSE IF ( FIRST .OR. INTERM ) THEN
-                  MINWRK = NR*( M + L + 1 )
-               ELSE
-                  MINWRK = 2*NR*( M + L + 1 ) + NR
-               END IF
-            ELSE
-               MINWRK = 2*NR
-               MAXWRK = NR + NR*ILAENV( 1, 'DGEQRF', ' ', NS, NR, -1,
-     $                                  -1 )
-               IF ( FIRST ) THEN
-                  IF ( LDR.LT.NS ) THEN
-                     MINWRK = MINWRK + NR
-                     MAXWRK = NS*NR + MAXWRK
-                  END IF
-               ELSE
-                  IF ( CONNEC ) THEN
-                     MINWRK = MINWRK*( NOBR + 1 )
-                  ELSE
-                     MINWRK = MINWRK + NR
-                  END IF
-                  MAXWRK = NS*NR + MAXWRK
-               END IF
-            END IF
-            MAXWRK = MAX( MINWRK, MAXWRK )
-C
-            IF( LDWORK.LT.MINWRK ) THEN
-               INFO = -17
-               DWORK( 1 ) = MINWRK
-            END IF
-         END IF
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01MD', -INFO )
-         RETURN
-      END IF
-C
-      IF ( CHALG ) THEN
-C
-C        Compute the  R  factor from a Cholesky factorization of the
-C        input-output data correlation matrix.
-C
-C        Set the parameters for constructing the correlations of the
-C        current block.
-C
-         LDRWRK = 2*NOBR2 - 2
-         IF( FIRST ) THEN
-            UPD = ZERO
-         ELSE
-            UPD = ONE
-         END IF
-C
-         IF( .NOT.FIRST .AND. CONNEC ) THEN
-C
-C           Restore the saved (M+L)*(2*NOBR-1) "connection" elements of
-C           U  and  Y  into their appropriate position in sequential
-C           processing. The process is performed column-wise, in
-C           reverse order, first for  Y  and then for  U.
-C           Workspace: need   (4*NOBR-2)*(M+L).
-C
-            IREV =     NR - M - L   - NOBR21 + 1
-            ICOL = 2*( NR - M - L ) - LDRWRK + 1
-C
-            DO 10 J = 2, M + L
-               DO 5 I = NOBR21 - 1, 0, -1
-                  DWORK(ICOL+I) = DWORK(IREV+I)
-    5          CONTINUE
-               IREV = IREV - NOBR21
-               ICOL = ICOL - LDRWRK
-   10       CONTINUE
-C
-            IF ( M.GT.0 )
-     $         CALL DLACPY( 'Full', NOBR21, M, U, LDU, DWORK(NOBR2),
-     $                      LDRWRK )
-            CALL DLACPY( 'Full', NOBR21, L, Y, LDY,
-     $                   DWORK(LDRWRK*M+NOBR2), LDRWRK )
-         END IF
-C
-         IF ( M.GT.0 ) THEN
-C
-C           Let  Guu(i,j) = Guu0(i,j) + u_i*u_j' + u_(i+1)*u_(j+1)' +
-C                                 ... + u_(i+NS-1)*u_(j+NS-1)',
-C           where  u_i'  is the i-th row of  U,  j = 1 : 2s,  i = 1 : j,
-C           NS = NSMP - 2s + 1,  and  Guu0(i,j)  is a zero matrix for
-C           BATCH = 'O' or 'F', and it is the matrix Guu(i,j) computed
-C           till the current block for BATCH = 'I' or 'L'. The matrix
-C           Guu(i,j)  is  m-by-m,  and  Guu(j,j)  is symmetric. The
-C           upper triangle of the U-U correlations,  Guu,  is computed
-C           (or updated) column-wise in the array  R,  that is, in the
-C           order  Guu(1,1),  Guu(1,2),  Guu(2,2),  ...,  Guu(2s,2s).
-C           Only the submatrices of the first block-row are fully
-C           computed (or updated). The remaining ones are determined
-C           exploiting the block-Hankel structure, using the updating
-C           formula
-C
-C           Guu(i+1,j+1) = Guu0(i+1,j+1) - Guu0(i,j) + Guu(i,j) +
-C                                 u_(i+NS)*u_(j+NS)' - u_i*u_j'.
-C
-            IF( .NOT.FIRST ) THEN
-C
-C              Subtract the contribution of the previous block of data
-C              in sequential processing. The columns must be processed
-C              in backward order.
-C
-               DO 20 I = NOBR21*M, 1, -1
-                  CALL DAXPY( I, -ONE, R(1,I), 1, R(M+1,M+I), 1 )
-   20          CONTINUE
-C
-            END IF
-C
-C           Compute/update  Guu(1,1).
-C
-            IF( .NOT.FIRST .AND. CONNEC )
-     $         CALL DSYRK( 'Upper', 'Transpose', M, NOBR21, ONE, DWORK,
-     $                     LDRWRK, UPD, R, LDR )
-            CALL DSYRK( 'Upper', 'Transpose', M, NS, ONE, U, LDU, UPD,
-     $                  R, LDR )
-C
-            JD = 1
-C
-            IF( FIRST .OR. .NOT.CONNEC ) THEN
-C
-               DO 70 J = 2, NOBR2
-                  JD = JD + M
-                  ID = M  + 1
-C
-C                 Compute/update  Guu(1,j).
-C
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, M, NS, ONE,
-     $                        U, LDU, U(J,1), LDU, UPD, R(1,JD), LDR )
-C
-C                 Compute/update  Guu(2:j,j), exploiting the
-C                 block-Hankel structure.
-C
-                  IF( FIRST ) THEN
-C
-                     DO 30 I = JD - M, JD - 1
-                        CALL DCOPY( I, R(1,I), 1, R(M+1,M+I), 1 )
-   30                CONTINUE
-C
-                  ELSE
-C
-                     DO 40 I = JD - M, JD - 1
-                        CALL DAXPY( I, ONE, R(1,I), 1, R(M+1,M+I), 1 )
-   40                CONTINUE
-C
-                  END IF
-C
-                  DO 50 I = 2, J - 1
-                     CALL DGER( M, M, ONE, U(NS+I-1,1), LDU,
-     $                          U(NS+J-1,1), LDU, R(ID,JD), LDR )
-                     CALL DGER( M, M, -ONE, U(I-1,1), LDU, U(J-1,1),
-     $                          LDU, R(ID,JD), LDR )
-                     ID = ID + M
-   50             CONTINUE
-C
-                  DO 60 I = 1, M
-                     CALL DAXPY( I, U(NS+J-1,I), U(NS+J-1,1), LDU,
-     $                           R(JD,JD+I-1), 1 )
-                     CALL DAXPY( I, -U(J-1,I), U(J-1,1), LDU,
-     $                           R(JD,JD+I-1), 1 )
-   60             CONTINUE
-C
-   70          CONTINUE
-C
-            ELSE
-C
-               DO 120 J = 2, NOBR2
-                  JD = JD + M
-                  ID = M  + 1
-C
-C                 Compute/update  Guu(1,j)  for sequential processing
-C                 with connected blocks.
-C
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, M, NOBR21,
-     $                        ONE, DWORK, LDRWRK, DWORK(J), LDRWRK, UPD,
-     $                        R(1,JD), LDR )
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, M, NS, ONE,
-     $                        U, LDU, U(J,1), LDU, ONE, R(1,JD), LDR )
-C
-C                 Compute/update  Guu(2:j,j)  for sequential processing
-C                 with connected blocks, exploiting the block-Hankel
-C                 structure.
-C
-                  IF( FIRST ) THEN
-C
-                     DO 80 I = JD - M, JD - 1
-                        CALL DCOPY( I, R(1,I), 1, R(M+1,M+I), 1 )
-   80                CONTINUE
-C
-                  ELSE
-C
-                     DO 90 I = JD - M, JD - 1
-                        CALL DAXPY( I, ONE, R(1,I), 1, R(M+1,M+I), 1 )
-   90                CONTINUE
-C
-                  END IF
-C
-                  DO 100 I = 2, J - 1
-                     CALL DGER( M, M, ONE, U(NS+I-1,1), LDU,
-     $                          U(NS+J-1,1), LDU, R(ID,JD), LDR )
-                     CALL DGER( M, M, -ONE, DWORK(I-1), LDRWRK,
-     $                          DWORK(J-1), LDRWRK, R(ID,JD), LDR )
-                     ID = ID + M
-  100             CONTINUE
-C
-                  DO 110 I = 1, M
-                     CALL DAXPY( I, U(NS+J-1,I), U(NS+J-1,1), LDU,
-     $                           R(JD,JD+I-1), 1 )
-                     CALL DAXPY( I, -DWORK((I-1)*LDRWRK+J-1),
-     $                           DWORK(J-1), LDRWRK, R(JD,JD+I-1), 1 )
-  110             CONTINUE
-C
-  120          CONTINUE
-C
-            END IF
-C
-            IF ( LAST .AND. MOESP ) THEN
-C
-C              Interchange past and future parts for MOESP algorithm.
-C              (Only the upper triangular parts are interchanged, and
-C              the (1,2) part is transposed in-situ.)
-C
-               TEMP = R(1,1)
-               R(1,1) = R(MNOBR+1,MNOBR+1)
-               R(MNOBR+1,MNOBR+1) = TEMP
-C
-               DO 130 J = 2, MNOBR
-                  CALL DSWAP( J, R(1,J), 1, R(MNOBR+1,MNOBR+J), 1 )
-                  CALL DSWAP( J-1, R(1,MNOBR+J), 1, R(J,MNOBR+1), LDR )
-  130          CONTINUE
-C
-            END IF
-C
-C           Let  Guy(i,j) = Guy0(i,j) + u_i*y_j' + u_(i+1)*y_(j+1)' +
-C                                 ... + u_(i+NS-1)*y_(j+NS-1)',
-C           where  u_i'  is the i-th row of  U,  y_j'  is the j-th row
-C           of  Y,  j = 1 : 2s,  i = 1 : 2s,  NS = NSMP - 2s + 1,  and
-C           Guy0(i,j)  is a zero matrix for  BATCH = 'O' or 'F', and it
-C           is the matrix Guy(i,j) computed till the current block for
-C           BATCH = 'I' or 'L'.  Guy(i,j) is m-by-L. The U-Y
-C           correlations,  Guy,  are computed (or updated) column-wise
-C           in the array  R. Only the submatrices of the first block-
-C           column and block-row are fully computed (or updated). The
-C           remaining ones are determined exploiting the block-Hankel
-C           structure, using the updating formula
-C
-C           Guy(i+1,j+1) = Guy0(i+1,j+1) - Guy0(i,j) + Guy(i,j) +
-C                                 u_(i+NS)*y(j+NS)' - u_i*y_j'.
-C
-            II = MMNOBR - M
-            IF( .NOT.FIRST ) THEN
-C
-C              Subtract the contribution of the previous block of data
-C              in sequential processing. The columns must be processed
-C              in backward order.
-C
-               DO 140 I = NR - L, MMNOBR + 1, -1
-                  CALL DAXPY( II, -ONE, R(1,I), 1, R(M+1,L+I), 1 )
-  140          CONTINUE
-C
-            END IF
-C
-C           Compute/update the first block-column of  Guy,  Guy(i,1).
-C
-            IF( FIRST .OR. .NOT.CONNEC ) THEN
-C
-               DO 150 I = 1, NOBR2
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, L, NS, ONE,
-     $                        U(I,1), LDU, Y, LDY, UPD,
-     $                        R((I-1)*M+1,MMNOBR+1), LDR )
-  150          CONTINUE
-C
-            ELSE
-C
-               DO 160 I = 1, NOBR2
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, L, NOBR21,
-     $                        ONE, DWORK(I), LDRWRK, DWORK(LDRWRK*M+1),
-     $                        LDRWRK, UPD, R((I-1)*M+1,MMNOBR+1), LDR )
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, L, NS, ONE,
-     $                        U(I,1), LDU, Y, LDY, ONE,
-     $                        R((I-1)*M+1,MMNOBR+1), LDR )
-  160          CONTINUE
-C
-            END IF
-C
-            JD = MMNOBR + 1
-C
-            IF( FIRST .OR. .NOT.CONNEC ) THEN
-C
-               DO 200 J = 2, NOBR2
-                  JD = JD + L
-                  ID = M  + 1
-C
-C                 Compute/update  Guy(1,j).
-C
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, L, NS, ONE,
-     $                        U, LDU, Y(J,1), LDY, UPD, R(1,JD), LDR )
-C
-C                 Compute/update  Guy(2:2*s,j), exploiting the
-C                 block-Hankel structure.
-C
-                  IF( FIRST ) THEN
-C
-                     DO 170 I = JD - L, JD - 1
-                        CALL DCOPY( II, R(1,I), 1, R(M+1,L+I), 1 )
-  170                CONTINUE
-C
-                  ELSE
-C
-                     DO 180 I = JD - L, JD - 1
-                        CALL DAXPY( II, ONE, R(1,I), 1, R(M+1,L+I), 1 )
-  180                CONTINUE
-C
-                  END IF
-C
-                  DO 190 I = 2, NOBR2
-                     CALL DGER( M, L, ONE, U(NS+I-1,1), LDU,
-     $                          Y(NS+J-1,1), LDY, R(ID,JD), LDR )
-                     CALL DGER( M, L, -ONE, U(I-1,1), LDU, Y(J-1,1),
-     $                          LDY, R(ID,JD), LDR )
-                     ID = ID + M
-  190             CONTINUE
-C
-  200          CONTINUE
-C
-            ELSE
-C
-               DO 240 J = 2, NOBR2
-                  JD = JD + L
-                  ID = M  + 1
-C
-C                 Compute/update  Guy(1,j)  for sequential processing
-C                 with connected blocks.
-C
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, L, NOBR21,
-     $                        ONE, DWORK, LDRWRK, DWORK(LDRWRK*M+J),
-     $                        LDRWRK, UPD, R(1,JD), LDR )
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, L, NS, ONE,
-     $                        U, LDU, Y(J,1), LDY, ONE, R(1,JD), LDR )
-C
-C                 Compute/update  Guy(2:2*s,j)  for sequential
-C                 processing with connected blocks, exploiting the
-C                 block-Hankel structure.
-C
-                  IF( FIRST ) THEN
-C
-                     DO 210 I = JD - L, JD - 1
-                        CALL DCOPY( II, R(1,I), 1, R(M+1,L+I), 1 )
-  210                CONTINUE
-C
-                  ELSE
-C
-                     DO 220 I = JD - L, JD - 1
-                        CALL DAXPY( II, ONE, R(1,I), 1, R(M+1,L+I), 1 )
-  220                CONTINUE
-C
-                  END IF
-C
-                  DO 230 I = 2, NOBR2
-                     CALL DGER( M, L, ONE, U(NS+I-1,1), LDU,
-     $                          Y(NS+J-1,1), LDY, R(ID,JD), LDR )
-                     CALL DGER( M, L, -ONE, DWORK(I-1), LDRWRK,
-     $                          DWORK(LDRWRK*M+J-1), LDRWRK, R(ID,JD),
-     $                          LDR )
-                     ID = ID + M
-  230             CONTINUE
-C
-  240          CONTINUE
-C
-            END IF
-C
-            IF ( LAST .AND. MOESP ) THEN
-C
-C              Interchange past and future parts of U-Y correlations
-C              for MOESP algorithm.
-C
-               DO 250 J = MMNOBR + 1, NR
-                  CALL DSWAP( MNOBR, R(1,J), 1, R(MNOBR+1,J), 1 )
-  250          CONTINUE
-C
-            END IF
-         END IF
-C
-C        Let  Gyy(i,j) = Gyy0(i,j) + y_i*y_i' + y_(i+1)*y_(i+1)' + ... +
-C                                    y_(i+NS-1)*y_(i+NS-1)',
-C        where  y_i'  is the i-th row of  Y,  j = 1 : 2s,  i = 1 : j,
-C        NS = NSMP - 2s + 1,  and  Gyy0(i,j)  is a zero matrix for
-C        BATCH = 'O' or 'F', and it is the matrix Gyy(i,j) computed till
-C        the current block for BATCH = 'I' or 'L'.  Gyy(i,j) is L-by-L,
-C        and  Gyy(j,j)  is symmetric. The upper triangle of the Y-Y
-C        correlations,  Gyy,  is computed (or updated) column-wise in
-C        the corresponding part of the array  R,  that is, in the order
-C        Gyy(1,1),  Gyy(1,2),  Gyy(2,2),  ...,  Gyy(2s,2s).  Only the
-C        submatrices of the first block-row are fully computed (or
-C        updated). The remaining ones are determined exploiting the
-C        block-Hankel structure, using the updating formula
-C
-C        Gyy(i+1,j+1) = Gyy0(i+1,j+1) - Gyy0(i,j) + Gyy(i,j) +
-C                              y_(i+NS)*y_(j+NS)' - y_i*y_j'.
-C
-         JD = MMNOBR + 1
-C
-         IF( .NOT.FIRST ) THEN
-C
-C           Subtract the contribution of the previous block of data
-C           in sequential processing. The columns must be processed in
-C           backward order.
-C
-            DO 260 I = NR - L, MMNOBR + 1, -1
-               CALL DAXPY( I-MMNOBR, -ONE, R(JD,I), 1, R(JD+L,L+I), 1 )
-  260       CONTINUE
-C
-         END IF
-C
-C        Compute/update  Gyy(1,1).
-C
-         IF( .NOT.FIRST .AND. CONNEC )
-     $      CALL DSYRK( 'Upper', 'Transpose', L, NOBR21, ONE,
-     $                  DWORK(LDRWRK*M+1), LDRWRK, UPD, R(JD,JD), LDR )
-         CALL DSYRK( 'Upper', 'Transpose', L, NS, ONE, Y, LDY, UPD,
-     $               R(JD,JD), LDR )
-C
-         IF( FIRST .OR. .NOT.CONNEC ) THEN
-C
-            DO 310 J = 2, NOBR2
-               JD = JD + L
-               ID = MMNOBR + L + 1
-C
-C              Compute/update  Gyy(1,j).
-C
-               CALL DGEMM( 'Transpose', 'NoTranspose', L, L, NS, ONE, Y,
-     $                     LDY, Y(J,1), LDY, UPD, R(MMNOBR+1,JD), LDR )
-C
-C              Compute/update  Gyy(2:j,j), exploiting the block-Hankel
-C              structure.
-C
-               IF( FIRST ) THEN
-C
-                  DO 270 I = JD - L, JD - 1
-                     CALL DCOPY( I-MMNOBR, R(MMNOBR+1,I), 1,
-     $                           R(MMNOBR+L+1,L+I), 1 )
-  270             CONTINUE
-C
-               ELSE
-C
-                  DO 280 I = JD - L, JD - 1
-                     CALL DAXPY( I-MMNOBR, ONE, R(MMNOBR+1,I), 1,
-     $                           R(MMNOBR+L+1,L+I), 1 )
-  280             CONTINUE
-C
-               END IF
-C
-               DO 290 I = 2, J - 1
-                  CALL DGER( L, L, ONE, Y(NS+I-1,1), LDY, Y(NS+J-1,1),
-     $                       LDY, R(ID,JD), LDR )
-                  CALL DGER( L, L, -ONE, Y(I-1,1), LDY, Y(J-1,1), LDY,
-     $                       R(ID,JD), LDR )
-                  ID = ID + L
-  290          CONTINUE
-C
-               DO 300 I = 1, L
-                  CALL DAXPY( I, Y(NS+J-1,I), Y(NS+J-1,1), LDY,
-     $                        R(JD,JD+I-1), 1 )
-                  CALL DAXPY( I, -Y(J-1,I), Y(J-1,1), LDY, R(JD,JD+I-1),
-     $                        1 )
-  300          CONTINUE
-C
-  310       CONTINUE
-C
-         ELSE
-C
-            DO 360 J = 2, NOBR2
-               JD = JD + L
-               ID = MMNOBR + L + 1
-C
-C              Compute/update  Gyy(1,j)  for sequential processing with
-C              connected blocks.
-C
-               CALL DGEMM( 'Transpose', 'NoTranspose', L, L, NOBR21,
-     $                     ONE, DWORK(LDRWRK*M+1), LDRWRK,
-     $                     DWORK(LDRWRK*M+J), LDRWRK, UPD,
-     $                     R(MMNOBR+1,JD), LDR )
-               CALL DGEMM( 'Transpose', 'NoTranspose', L, L, NS, ONE, Y,
-     $                     LDY, Y(J,1), LDY, ONE, R(MMNOBR+1,JD), LDR )
-C
-C              Compute/update  Gyy(2:j,j)  for sequential processing
-C              with connected blocks, exploiting the block-Hankel
-C              structure.
-C
-               IF( FIRST ) THEN
-C
-                  DO 320 I = JD - L, JD - 1
-                     CALL DCOPY( I-MMNOBR, R(MMNOBR+1,I), 1,
-     $                           R(MMNOBR+L+1,L+I), 1 )
-  320             CONTINUE
-C
-               ELSE
-C
-                  DO 330 I = JD - L, JD - 1
-                     CALL DAXPY( I-MMNOBR, ONE, R(MMNOBR+1,I), 1,
-     $                           R(MMNOBR+L+1,L+I), 1 )
-  330             CONTINUE
-C
-               END IF
-C
-               DO 340 I = 2, J - 1
-                  CALL DGER( L, L, ONE, Y(NS+I-1,1), LDY, Y(NS+J-1,1),
-     $                       LDY, R(ID,JD), LDR )
-                  CALL DGER( L, L, -ONE, DWORK(LDRWRK*M+I-1), LDRWRK,
-     $                       DWORK(LDRWRK*M+J-1), LDRWRK, R(ID,JD),
-     $                       LDR )
-                  ID = ID + L
-  340          CONTINUE
-C
-               DO 350 I = 1, L
-                  CALL DAXPY( I, Y(NS+J-1,I), Y(NS+J-1,1), LDY,
-     $                        R(JD,JD+I-1), 1 )
-                  CALL DAXPY( I, -DWORK(LDRWRK*(M+I-1)+J-1),
-     $                        DWORK(LDRWRK*M+J-1), LDRWRK, R(JD,JD+I-1),
-     $                        1 )
-  350          CONTINUE
-C
-  360       CONTINUE
-C
-         END IF
-C
-         IF ( .NOT.LAST ) THEN
-            IF ( CONNEC ) THEN
-C
-C              For sequential processing with connected data blocks,
-C              save the remaining ("connection") elements of  U  and  Y
-C              in the first  (M+L)*(2*NOBR-1)  locations of  DWORK.
-C
-               IF ( M.GT.0 )
-     $            CALL DLACPY( 'Full', NOBR21, M, U(NS+1,1), LDU, DWORK,
-     $                         NOBR21 )
-               CALL DLACPY( 'Full', NOBR21, L, Y(NS+1,1), LDY,
-     $                      DWORK(MMNOBR-M+1), NOBR21 )
-            END IF
-C
-C           Return to get new data.
-C
-            ICYCLE = ICYCLE + 1
-            IF ( ICYCLE.GT.MAXCYC )
-     $         IWARN = 1
-            RETURN
-C
-         ELSE
-C
-C           Try to compute the Cholesky factor of the correlation
-C           matrix.
-C
-            CALL DPOTRF( 'Upper', NR, R, LDR, IERR )
-            GO TO 370
-         END IF
-      ELSE IF ( FQRALG ) THEN
-C
-C        Compute the  R  factor from a fast QR factorization of the
-C        input-output data correlation matrix.
-C
-         CALL IB01MY( METH, BATCH, CONCT, NOBR, M, L, NSMP, U, LDU,
-     $                Y, LDY, R, LDR, IWORK, DWORK, LDWORK, IWARN,
-     $                IERR )
-         IF( .NOT.LAST )
-     $      RETURN
-         MAXWRK = MAX( MAXWRK, INT( DWORK(1) ) )
-      END IF
-C
-  370 CONTINUE
-C
-      IF( IERR.NE.0 ) THEN
-C
-C        Error return from a fast factorization algorithm of the
-C        input-output data correlation matrix.
-C
-         IF( ONEBCH ) THEN
-            QRALG  = .TRUE.
-            IWARN  = 2
-            MINWRK = 2*NR
-            MAXWRK = NR + NR*ILAENV( 1, 'DGEQRF', ' ', NS, NR, -1,
-     $                               -1 )
-            IF ( LDR.LT.NS ) THEN
-               MINWRK = MINWRK + NR
-               MAXWRK = NS*NR + MAXWRK
-            END IF
-            MAXWRK = MAX( MINWRK, MAXWRK )
-C
-            IF( LDWORK.LT.MINWRK ) THEN
-               INFO = -17
-C
-C              Return: Not enough workspace.
-C
-               DWORK( 1 ) = MINWRK
-               CALL XERBLA( 'IB01MD', -INFO )
-               RETURN
-            END IF
-         ELSE
-            INFO = 1
-            RETURN
-         END IF
-      END IF
-C
-      IF ( QRALG ) THEN
-C
-C        Compute the  R  factor from a QR factorization of the matrix  H
-C        of concatenated block Hankel matrices.
-C
-C        Construct the matrix  H.
-C
-C        Set the parameters for constructing the current segment of the
-C        Hankel matrix, taking the available memory space into account.
-C        INITI+1 points to the beginning rows of  U  and  Y  from which
-C                data are taken when NCYCLE > 1 inner cycles are needed,
-C                or for sequential processing with connected blocks.
-C        LDRWMX is the number of rows that can fit in the working space.
-C        LDRWRK is the actual number of rows processed in this space.
-C        NSLAST is the number of samples to be processed at the last
-C               inner cycle.
-C
-         INITI  = 0
-         LDRWMX = LDWORK / NR - 2
-         NCYCLE = 1
-         NSLAST = NSMP
-         LINR   = .FALSE.
-         IF ( FIRST ) THEN
-            LINR   = LDR.GE.NS
-            LDRWRK = NS
-         ELSE IF ( CONNEC ) THEN
-            LDRWRK = NSMP
-         ELSE
-            LDRWRK = NS
-         END IF
-         INICYC = 1
-C
-         IF ( .NOT.LINR ) THEN
-            IF ( LDRWMX.LT.LDRWRK ) THEN
-C
-C              Not enough working space for doing a single inner cycle.
-C              NCYCLE inner cycles are to be performed for the current
-C              data block using the working space.
-C
-               NCYCLE = LDRWRK / LDRWMX
-               NSLAST = MOD( LDRWRK, LDRWMX )
-               IF ( NSLAST.NE.0 ) THEN
-                  NCYCLE = NCYCLE + 1
-               ELSE
-                  NSLAST = LDRWMX
-               END IF
-               LDRWRK = LDRWMX
-               NS = LDRWRK
-               IF ( FIRST ) INICYC = 2
-            END IF
-            MLDRW = M*LDRWRK
-            LLDRW = L*LDRWRK
-            INU = MLDRW*NOBR  + 1
-            INY = MLDRW*NOBR2 + 1
-         END IF
-C
-C        Process the data given at the current call.
-C
-         IF ( .NOT.FIRST .AND. CONNEC ) THEN
-C
-C           Restore the saved (M+L)*(2*NOBR-1) "connection" elements of
-C           U  and  Y  into their appropriate position in sequential
-C           processing. The process is performed column-wise, in
-C           reverse order, first for  Y  and then for  U.
-C
-            IREV = NR - M - L - NOBR21 + 1
-            ICOL = INY + LLDRW - LDRWRK
-C
-            DO 380 J = 1, L
-               DO 375 I = NOBR21 - 1, 0, -1
-                  DWORK(ICOL+I) = DWORK(IREV+I)
-  375          CONTINUE
-               IREV = IREV - NOBR21
-               ICOL = ICOL - LDRWRK
-  380       CONTINUE
-C
-            IF( MOESP ) THEN
-               ICOL = INU + MLDRW - LDRWRK
-            ELSE
-               ICOL = MLDRW - LDRWRK + 1
-            END IF
-C
-            DO 390 J = 1, M
-               DO 385 I = NOBR21 - 1, 0, -1
-                  DWORK(ICOL+I) = DWORK(IREV+I)
-  385          CONTINUE
-               IREV = IREV - NOBR21
-               ICOL = ICOL - LDRWRK
-  390       CONTINUE
-C
-            IF( MOESP )
-     $         CALL DLACPY( 'Full', NOBRM1, M, DWORK(INU+NOBR), LDRWRK,
-     $                      DWORK, LDRWRK )
-         END IF
-C
-C        Data compression using QR factorization.
-C
-         IF ( FIRST ) THEN
-C
-C           Non-sequential data processing or first block in
-C           sequential data processing:
-C           Use the general QR factorization algorithm.
-C
-            IF ( LINR ) THEN
-C
-C              Put the input-output data in the array  R.
-C
-               IF( M.GT.0 ) THEN
-                  IF( MOESP ) THEN
-C
-                     DO 400 I = 1, NOBR
-                        CALL DLACPY( 'Full', NS, M, U(NOBR+I,1), LDU,
-     $                               R(1,M*(I-1)+1), LDR )
-  400                CONTINUE
-C
-                     DO 410 I = 1, NOBR
-                        CALL DLACPY( 'Full', NS, M, U(I,1), LDU,
-     $                               R(1,MNOBR+M*(I-1)+1), LDR )
-  410                CONTINUE
-C
-                  ELSE
-C
-                     DO 420 I = 1, NOBR2
-                        CALL DLACPY( 'Full', NS, M, U(I,1), LDU,
-     $                               R(1,M*(I-1)+1), LDR )
-  420                CONTINUE
-C
-                  END IF
-               END IF
-C
-               DO 430 I = 1, NOBR2
-                  CALL DLACPY( 'Full', NS, L, Y(I,1), LDY,
-     $                         R(1,MMNOBR+L*(I-1)+1), LDR )
-  430          CONTINUE
-C
-C              Workspace: need   4*(M+L)*NOBR,
-C                         prefer 2*(M+L)*NOBR+2*(M+L)*NOBR*NB.
-C
-               ITAU  = 1
-               JWORK = ITAU + NR
-               CALL DGEQRF( NS, NR, R, LDR, DWORK(ITAU), DWORK(JWORK),
-     $                      LDWORK-JWORK+1, IERR )
-            ELSE
-C
-C              Put the input-output data in the array  DWORK.
-C
-               IF( M.GT.0 ) THEN
-                  ISHFTU = 1
-                  IF( MOESP ) THEN
-                     ISHFT2 = INU
-C
-                     DO 440 I = 1, NOBR
-                        CALL DLACPY( 'Full', NS, M, U(NOBR+I,1), LDU,
-     $                               DWORK(ISHFTU), LDRWRK )
-                        ISHFTU = ISHFTU + MLDRW
-  440                CONTINUE
-C
-                     DO 450 I = 1, NOBR
-                        CALL DLACPY( 'Full', NS, M, U(I,1), LDU,
-     $                               DWORK(ISHFT2), LDRWRK )
-                        ISHFT2 = ISHFT2 + MLDRW
-  450                CONTINUE
-C
-                  ELSE
-C
-                     DO 460 I = 1, NOBR2
-                        CALL DLACPY( 'Full', NS, M, U(I,1), LDU,
-     $                               DWORK(ISHFTU), LDRWRK )
-                        ISHFTU = ISHFTU + MLDRW
-  460                CONTINUE
-C
-                  END IF
-               END IF
-C
-               ISHFTY = INY
-C
-               DO 470 I = 1, NOBR2
-                  CALL DLACPY( 'Full', NS, L, Y(I,1), LDY,
-     $                         DWORK(ISHFTY), LDRWRK )
-                  ISHFTY = ISHFTY + LLDRW
-  470          CONTINUE
-C
-C              Workspace: need   2*(M+L)*NOBR + 4*(M+L)*NOBR,
-C                         prefer NS*2*(M+L)*NOBR + 2*(M+L)*NOBR
-C                                                + 2*(M+L)*NOBR*NB,
-C                         used LDRWRK*2*(M+L)*NOBR + 4*(M+L)*NOBR,
-C                         where  NS = NSMP - 2*NOBR + 1,
-C                            LDRWRK = min(NS, LDWORK/(2*(M+L)*NOBR)-2).
-C
-               ITAU  = LDRWRK*NR + 1
-               JWORK = ITAU + NR
-               CALL DGEQRF( NS, NR, DWORK, LDRWRK, DWORK(ITAU),
-     $                      DWORK(JWORK), LDWORK-JWORK+1, IERR )
-               CALL DLACPY( 'Upper ', MIN(NS,NR), NR, DWORK, LDRWRK, R,
-     $                      LDR )
-            END IF
-C
-            IF ( NS.LT.NR )
-     $         CALL DLASET( 'Upper ', NR - NS, NR - NS, ZERO, ZERO,
-     $                      R(NS+1,NS+1), LDR )
-            INITI = INITI + NS
-         END IF
-C
-         IF ( NCYCLE.GT.1 .OR. .NOT.FIRST ) THEN
-C
-C           Remaining segments of the first data block or
-C           remaining segments/blocks in sequential data processing:
-C           Use a structure-exploiting QR factorization algorithm.
-C
-            NSL = LDRWRK
-            IF ( .NOT.CONNEC ) NSL = NS
-            ITAU  = LDRWRK*NR + 1
-            JWORK = ITAU + NR
-C
-            DO 560 NICYCL = INICYC, NCYCLE
-C
-C              INIT  denotes the beginning row where new data are put.
-C
-               IF ( CONNEC .AND. NICYCL.EQ.1 ) THEN
-                  INIT = NOBR2
-               ELSE
-                  INIT = 1
-               END IF
-               IF ( NCYCLE.GT.1 .AND. NICYCL.EQ.NCYCLE ) THEN
-C
-C                 Last samples in the last data segment of a block.
-C
-                  NS  = NSLAST
-                  NSL = NSLAST
-               END IF
-C
-C              Put the input-output data in the array  DWORK.
-C
-               NSF = NS
-               IF ( INIT.GT.1 .AND. NCYCLE.GT.1 ) NSF = NSF - NOBR21
-               IF ( M.GT.0 ) THEN
-                  ISHFTU = INIT
-C
-                  IF( MOESP ) THEN
-                     ISHFT2 = INIT + INU - 1
-C
-                     DO 480 I = 1, NOBR
-                        CALL DLACPY( 'Full', NSF, M, U(INITI+NOBR+I,1),
-     $                               LDU, DWORK(ISHFTU), LDRWRK )
-                        ISHFTU = ISHFTU + MLDRW
-  480                CONTINUE
-C
-                     DO 490 I = 1, NOBR
-                        CALL DLACPY( 'Full', NSF, M, U(INITI+I,1), LDU,
-     $                               DWORK(ISHFT2), LDRWRK )
-                        ISHFT2 = ISHFT2 + MLDRW
-  490                CONTINUE
-C
-                  ELSE
-C
-                     DO 500 I = 1, NOBR2
-                        CALL DLACPY( 'Full', NSF, M, U(INITI+I,1), LDU,
-     $                               DWORK(ISHFTU), LDRWRK )
-                        ISHFTU = ISHFTU + MLDRW
-  500                CONTINUE
-C
-                  END IF
-               END IF
-C
-               ISHFTY = INIT + INY - 1
-C
-               DO 510 I = 1, NOBR2
-                  CALL DLACPY( 'Full', NSF, L, Y(INITI+I,1), LDY,
-     $                         DWORK(ISHFTY), LDRWRK )
-                  ISHFTY = ISHFTY + LLDRW
-  510          CONTINUE
-C
-               IF ( INIT.GT.1 ) THEN
-C
-C                 Prepare the connection to the previous block of data
-C                 in sequential processing.
-C
-                  IF( MOESP .AND. M.GT.0 )
-     $               CALL DLACPY( 'Full', NOBR, M, U, LDU, DWORK(NOBR),
-     $                            LDRWRK )
-C
-C                 Shift the elements from the connection to the previous
-C                 block of data in sequential processing.
-C
-                  IF ( M.GT.0 ) THEN
-                     ISHFTU = MLDRW + 1
-C
-                     IF( MOESP ) THEN
-                        ISHFT2 = MLDRW + INU
-C
-                        DO 520 I = 1, NOBRM1
-                           CALL DLACPY( 'Full', NOBR21, M,
-     $                                  DWORK(ISHFTU-MLDRW+1), LDRWRK,
-     $                                  DWORK(ISHFTU), LDRWRK )
-                           ISHFTU = ISHFTU + MLDRW
-  520                  CONTINUE
-C
-                        DO 530 I = 1, NOBRM1
-                           CALL DLACPY( 'Full', NOBR21, M,
-     $                                  DWORK(ISHFT2-MLDRW+1), LDRWRK,
-     $                                  DWORK(ISHFT2), LDRWRK )
-                          ISHFT2 = ISHFT2 + MLDRW
-  530                  CONTINUE
-C
-                     ELSE
-C
-                        DO 540 I = 1, NOBR21
-                           CALL DLACPY( 'Full', NOBR21, M,
-     $                                  DWORK(ISHFTU-MLDRW+1), LDRWRK,
-     $                                  DWORK(ISHFTU), LDRWRK )
-                           ISHFTU = ISHFTU + MLDRW
-  540                   CONTINUE
-C
-                     END IF
-                  END IF
-C
-                  ISHFTY = LLDRW + INY
-C
-                  DO 550 I = 1, NOBR21
-                     CALL DLACPY( 'Full', NOBR21, L,
-     $                            DWORK(ISHFTY-LLDRW+1), LDRWRK,
-     $                            DWORK(ISHFTY), LDRWRK )
-                     ISHFTY = ISHFTY + LLDRW
-  550             CONTINUE
-C
-               END IF
-C
-C              Workspace: need LDRWRK*2*(M+L)*NOBR + 4*(M+L)*NOBR.
-C
-               CALL MB04OD( 'Full', NR, 0, NSL, R, LDR, DWORK, LDRWRK,
-     $                      DUM, NR, DUM, NR, DWORK(ITAU), DWORK(JWORK)
-     $                    )
-               INITI = INITI + NSF
-  560       CONTINUE
-C
-         END IF
-C
-         IF ( .NOT.LAST ) THEN
-            IF ( CONNEC ) THEN
-C
-C              For sequential processing with connected data blocks,
-C              save the remaining ("connection") elements of  U  and  Y
-C              in the first  (M+L)*(2*NOBR-1)  locations of  DWORK.
-C
-               IF ( M.GT.0 )
-     $            CALL DLACPY( 'Full', NOBR21, M, U(INITI+1,1), LDU,
-     $                         DWORK, NOBR21 )
-               CALL DLACPY( 'Full', NOBR21, L, Y(INITI+1,1), LDY,
-     $                      DWORK(MMNOBR-M+1), NOBR21 )
-            END IF
-C
-C           Return to get new data.
-C
-            ICYCLE = ICYCLE + 1
-            IF ( ICYCLE.LE.MAXCYC )
-     $         RETURN
-            IWARN  = 1
-            ICYCLE = 1
-C
-         END IF
-C
-      END IF
-C
-C     Return optimal workspace in  DWORK(1).
-C
-      DWORK( 1 ) = MAXWRK
-      IF ( LAST ) THEN
-         ICYCLE = 1
-         MAXWRK = 1
-         NSMPSM = 0
-      END IF
-      RETURN
-C
-C *** Last line of IB01MD ***
-      END
--- a/extra/control-devel/src/IB01MY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1094 +0,0 @@
-      SUBROUTINE IB01MY( METH, BATCH, CONCT, NOBR, M, L, NSMP, U, LDU,
-     $                   Y, LDY, R, LDR, IWORK, DWORK, LDWORK, IWARN,
-     $                   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 an upper triangular factor  R  of the concatenated
-C     block Hankel matrices using input-output data, via a fast QR
-C     algorithm based on displacement rank.  The input-output data can,
-C     optionally, be processed sequentially.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     METH    CHARACTER*1
-C             Specifies the subspace identification method to be used,
-C             as follows:
-C             = 'M':  MOESP  algorithm with past inputs and outputs;
-C             = 'N':  N4SID  algorithm.
-C
-C     BATCH   CHARACTER*1
-C             Specifies whether or not sequential data processing is to
-C             be used, and, for sequential processing, whether or not
-C             the current data block is the first block, an intermediate
-C             block, or the last block, as follows:
-C             = 'F':  the first block in sequential data processing;
-C             = 'I':  an intermediate block in sequential data
-C                     processing;
-C             = 'L':  the last block in sequential data processing;
-C             = 'O':  one block only (non-sequential data processing).
-C             NOTE that when  100  cycles of sequential data processing
-C                  are completed for  BATCH = 'I',  a warning is
-C                  issued, to prevent for an infinite loop.
-C
-C     CONCT   CHARACTER*1
-C             Specifies whether or not the successive data blocks in
-C             sequential data processing belong to a single experiment,
-C             as follows:
-C             = 'C':  the current data block is a continuation of the
-C                     previous data block and/or it will be continued
-C                     by the next data block;
-C             = 'N':  there is no connection between the current data
-C                     block and the previous and/or the next ones.
-C             This parameter is not used if BATCH = 'O'.
-C
-C     Input/Output Parameters
-C
-C     NOBR    (input) INTEGER
-C             The number of block rows,  s,  in the input and output
-C             block Hankel matrices to be processed.  NOBR > 0.
-C             (In the MOESP theory,  NOBR  should be larger than  n, the
-C             estimated dimension of state vector.)
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C             When M = 0, no system inputs are processed.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     NSMP    (input) INTEGER
-C             The number of rows of matrices  U  and  Y  (number of
-C             samples,  t). (When sequential data processing is used,
-C             NSMP  is the number of samples of the current data
-C             block.)
-C             NSMP >= 2*(M+L+1)*NOBR - 1,  for non-sequential
-C                                          processing;
-C             NSMP >= 2*NOBR,  for sequential processing.
-C             The total number of samples when calling the routine with
-C             BATCH = 'L'  should be at least  2*(M+L+1)*NOBR - 1.
-C             The  NSMP  argument may vary from a cycle to another in
-C             sequential data processing, but  NOBR, M,  and  L  should
-C             be kept constant. For efficiency, it is advisable to use
-C             NSMP  as large as possible.
-C
-C     U       (input) DOUBLE PRECISION array, dimension (LDU,M)
-C             The leading NSMP-by-M part of this array must contain the
-C             t-by-m input-data sequence matrix  U,
-C             U = [u_1 u_2 ... u_m].  Column  j  of  U  contains the
-C             NSMP  values of the j-th input component for consecutive
-C             time increments.
-C             If M = 0, this array is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of the array U.
-C             LDU >= NSMP, if M > 0;
-C             LDU >= 1,    if M = 0.
-C
-C     Y       (input) DOUBLE PRECISION array, dimension (LDY,L)
-C             The leading NSMP-by-L part of this array must contain the
-C             t-by-l output-data sequence matrix  Y,
-C             Y = [y_1 y_2 ... y_l].  Column  j  of  Y  contains the
-C             NSMP  values of the j-th output component for consecutive
-C             time increments.
-C
-C     LDY     INTEGER
-C             The leading dimension of the array Y.  LDY >= NSMP.
-C
-C     R       (output) DOUBLE PRECISION array, dimension
-C             ( LDR,2*(M+L)*NOBR )
-C             If INFO = 0 and BATCH = 'L' or 'O', the leading
-C             2*(M+L)*NOBR-by-2*(M+L)*NOBR upper triangular part of this
-C             array contains the upper triangular factor R from the
-C             QR factorization of the concatenated block Hankel
-C             matrices.
-C
-C     LDR     INTEGER
-C             The leading dimension of the array  R.
-C             LDR >= 2*(M+L)*NOBR.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (M+L)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if  INFO = 0,  DWORK(1)  returns the optimal
-C             value of LDWORK.
-C             On exit, if  INFO = -16,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C             The first (M+L)*2*NOBR*(M+L+c) elements of  DWORK  should
-C             be preserved during successive calls of the routine
-C             with  BATCH = 'F'  or  'I',  till the final call with
-C             BATCH = 'L',  where
-C             c = 1,  if the successive data blocks do not belong to a
-C                     single experiment  (CONCT = 'N');
-C             c = 2,  if the successive data blocks belong to a single
-C                     experiment  (CONCT = 'C').
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= (M+L)*2*NOBR*(M+L+3),
-C                              if BATCH <> 'O' and CONCT = 'C';
-C             LDWORK >= (M+L)*2*NOBR*(M+L+1),
-C                              if BATCH = 'F' or 'I' and CONCT = 'N';
-C             LDWORK >= (M+L)*4*NOBR*(M+L+1)+(M+L)*2*NOBR,
-C                              if BATCH = 'L' and CONCT = 'N',
-C                              or BATCH = 'O'.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  the number of 100 cycles in sequential data
-C                   processing has been exhausted without signaling
-C                   that the last block of data was get.
-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 fast QR factorization algorithm failed. The
-C                   matrix H'*H is not (numerically) positive definite.
-C
-C     METHOD
-C
-C     Consider the  t x 2(m+l)s  matrix H of concatenated block Hankel
-C     matrices
-C
-C          H = [ Uf'         Up'      Y'      ],  for METH = 'M',
-C                  s+1,2s,t    1,s,t   1,2s,t
-C
-C          H = [ U'       Y'      ],              for METH = 'N',
-C                 1,2s,t   1,2s,t
-C
-C     where  Up     , Uf        , U      , and  Y        are block
-C              1,s,t    s+1,2s,t   1,2s,t        1,2s,t
-C     Hankel matrices defined in terms of the input and output data [3].
-C     The fast QR algorithm uses a factorization of H'*H which exploits
-C     the block-Hankel structure, via a displacement rank technique [5].
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Dewilde, P.
-C         Subspace Model Identification. Part 1: The output-error
-C         state-space model identification class of algorithms.
-C         Int. J. Control, 56, pp. 1187-1210, 1992.
-C
-C     [2] Verhaegen M.
-C         Subspace Model Identification. Part 3: Analysis of the
-C         ordinary output-error state-space model identification
-C         algorithm.
-C         Int. J. Control, 58, pp. 555-586, 1993.
-C
-C     [3] Verhaegen M.
-C         Identification of the deterministic part of MIMO state space
-C         models given in innovations form from input-output data.
-C         Automatica, Vol.30, No.1, pp.61-74, 1994.
-C
-C     [4] Van Overschee, P., and De Moor, B.
-C         N4SID: Subspace Algorithms for the Identification of
-C         Combined Deterministic-Stochastic Systems.
-C         Automatica, Vol.30, No.1, pp. 75-93, 1994.
-C
-C     [5] Kressner, D., Mastronardi, N., Sima, V., Van Dooren, P., and
-C         Van Huffel, S.
-C         A Fast Algorithm for Subspace State-space System
-C         Identification via Exploitation of the Displacement Structure.
-C         J. Comput. Appl. Math., Vol.132, No.1, pp. 71-81, 2001.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is reliable and efficient. Numerical
-C     difficulties are possible when the matrix H'*H is nearly rank
-C     defficient. The method cannot be used if the matrix H'*H is not
-C     numerically positive definite.
-C                                     2           3 2
-C     The algorithm requires 0(2t(m+l) s)+0(4(m+l) s ) floating point
-C     operations.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Katholieke Universiteit Leuven, June 2000.
-C     Partly based on Matlab codes developed by N. Mastronardi,
-C     Katholieke Universiteit Leuven, February 2000.
-C
-C     REVISIONS
-C
-C     V. Sima, July 2000, August 2000, Feb. 2004, May 2009.
-C
-C     KEYWORDS
-C
-C     Displacement rank, Hankel matrix, Householder transformation,
-C     identification methods, multivariable systems.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
-      INTEGER            MAXCYC
-      PARAMETER          ( MAXCYC = 100 )
-C     .. Scalar Arguments ..
-      INTEGER            INFO, IWARN, L, LDR, LDU, LDWORK, LDY, M, NOBR,
-     $                   NSMP
-      CHARACTER          BATCH, CONCT, METH
-C     .. Array Arguments ..
-      INTEGER            IWORK(*)
-      DOUBLE PRECISION   DWORK(*), R(LDR, *), U(LDU, *), Y(LDY, *)
-C     .. Local Scalars ..
-      DOUBLE PRECISION   BETA, CS, SN, UPD, TAU
-      INTEGER            I, ICJ, ICOL, ICONN, ICYCLE, IERR, IMAX, ING,
-     $                   INGC, INGP, IPG, IPGC, IPY, IREV, ITAU, J, JD,
-     $                   JDS, JWORK, K, LDRWRK, LLNOBR, LNOBR, LNRG,
-     $                   MAXWRK, MINWRK, MMNOBR, MNOBR, MNRG, NOBR2,
-     $                   NOBR21, NR, NRG, NS, NSM, NSMPSM
-      LOGICAL            CONNEC, FIRST, INTERM, LAST, MOESP, N4SID,
-     $                   ONEBCH
-C     .. Local Arrays ..
-      DOUBLE PRECISION   DUM(1)
-C     .. External Functions ..
-      LOGICAL            LSAME
-      INTEGER            IDAMAX
-      EXTERNAL           IDAMAX, LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DCOPY, DGEMM, DGEQRF, DLACPY, DLARF, DLARFG,
-     $                   DLASET, DORMQR, DSCAL, DSWAP, DSYRK, MA02ED,
-     $                   MA02FD, MB04ID, MB04OD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, INT, MAX, SQRT
-C     .. Save Statement ..
-C        ICYCLE  is used to count the cycles for  BATCH = 'I'.
-C        MAXWRK  is used to store the optimal workspace.
-C        NSMPSM  is used to sum up the  NSMP  values for  BATCH <> 'O'.
-      SAVE               ICYCLE, MAXWRK, NSMPSM
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode the scalar input parameters.
-C
-      MOESP  = LSAME( METH,  'M' )
-      N4SID  = LSAME( METH,  'N' )
-      ONEBCH = LSAME( BATCH, 'O' )
-      FIRST  = LSAME( BATCH, 'F' ) .OR. ONEBCH
-      INTERM = LSAME( BATCH, 'I' )
-      LAST   = LSAME( BATCH, 'L' ) .OR. ONEBCH
-      IF( .NOT.ONEBCH ) THEN
-         CONNEC = LSAME( CONCT, 'C' )
-      ELSE
-         CONNEC = .FALSE.
-      END IF
-      MNOBR  = M*NOBR
-      LNOBR  = L*NOBR
-      MMNOBR = MNOBR + MNOBR
-      LLNOBR = LNOBR + LNOBR
-      NOBR2  = 2*NOBR
-      NOBR21 = NOBR2 - 1
-      IWARN  = 0
-      INFO   = 0
-      IF( FIRST ) THEN
-         ICYCLE = 1
-         MAXWRK = 1
-         NSMPSM = 0
-      END IF
-      NSMPSM = NSMPSM + NSMP
-      NR     = MMNOBR + LLNOBR
-C
-C     Check the scalar input parameters.
-C
-      IF( .NOT.( MOESP .OR. N4SID ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( FIRST .OR. INTERM .OR. LAST ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ONEBCH ) THEN
-         IF( .NOT.( CONNEC .OR. LSAME( CONCT, 'N' ) ) )
-     $      INFO = -3
-      END IF
-      IF( INFO.EQ.0 ) THEN
-         IF( NOBR.LE.0 ) THEN
-            INFO = -4
-         ELSE IF( M.LT.0 ) THEN
-            INFO = -5
-         ELSE IF( L.LE.0 ) THEN
-            INFO = -6
-         ELSE IF( NSMP.LT.NOBR2 .OR.
-     $            ( LAST .AND. NSMPSM.LT.NR+NOBR21 ) ) THEN
-            INFO = -7
-         ELSE IF( LDU.LT.1 .OR. ( M.GT.0 .AND. LDU.LT.NSMP ) ) THEN
-            INFO = -9
-         ELSE IF( LDY.LT.NSMP ) THEN
-            INFO = -11
-         ELSE IF( LDR.LT.NR ) THEN
-            INFO = -13
-         ELSE
-C
-C           Compute workspace.
-C           NRG is the number of positive (or negative) generators.
-C
-            NRG = M + L + 1
-            IF ( .NOT.ONEBCH .AND. CONNEC ) THEN
-               MINWRK = NR*( NRG + 2 )
-            ELSE IF ( FIRST .OR. INTERM ) THEN
-               MINWRK = NR*NRG
-            ELSE
-               MINWRK = 2*NR*NRG + NR
-            END IF
-            MAXWRK = MAX( MINWRK, MAXWRK )
-C
-            IF( LDWORK.LT.MINWRK )
-     $         INFO = -16
-         END IF
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         NSMPSM = 0
-         IF ( INFO.EQ.-16 )
-     $      DWORK( 1 ) = MINWRK
-         CALL XERBLA( 'IB01MY', -INFO )
-         RETURN
-      END IF
-C
-C     Compute the  R  factor from a fast QR factorization of the
-C     matrix  H,  a concatenation of two block Hankel matrices.
-C     Specifically, a displacement rank technique is applied to
-C     the block Toeplitz matrix,  G = (P*H)'*(P*H),  where  P  is a
-C     2-by-2 block diagonal matrix, having as diagonal blocks identity
-C     matrices with columns taken in the reverse order.
-C     The technique builds and processes the generators of  G.  The
-C     matrices  G  and  G1 = H'*H  have the same  R  factor.
-C
-C     Set the parameters for constructing the correlations of the
-C     current block.
-C     NSM is the number of processed samples in U and Y, t - 2s.
-C     IPG and ING are pointers to the "positive" and "negative"
-C     generators, stored row-wise in the workspace. All "positive"
-C     generators are stored before any "negative" generators.
-C     If BATCH <> 'O' and CONCT = 'C', the "connection" elements of
-C     two successive batches are stored in the same workspace as the
-C     "negative" generators (which will be computed later on).
-C     IPY is a pointer to the Y part of the "positive" generators.
-C     LDRWRK is used as a leading dimension for the workspace part used
-C     to store the "connection" elements.
-C
-      NS   = NSMP - NOBR21
-      NSM  = NS - 1
-      MNRG = M*NRG
-      LNRG = L*NRG
-C
-      LDRWRK = 2*NOBR2
-      IF( FIRST ) THEN
-         UPD = ZERO
-      ELSE
-         UPD = ONE
-      END IF
-      DUM(1) = ZERO
-C
-      IPG   = 1
-      IPY   = IPG + M
-      ING   = IPG + NRG*NR
-      ICONN = ING
-C
-      IF( .NOT.FIRST .AND. CONNEC ) THEN
-C
-C        Restore the saved (M+L)*2*NOBR "connection" elements of
-C        U  and  Y  into their appropriate position in sequential
-C        processing. The process is performed column-wise, in
-C        reverse order, first for  Y  and then for  U.
-C        ICONN is a pointer to the first saved "connection" element.
-C        Workspace: need   (M+L)*2*NOBR*(M+L+3).
-C
-         IREV = ICONN +   NR
-         ICOL = ICONN + 2*NR
-C
-         DO 10 I = 2, M + L
-            IREV = IREV - NOBR2
-            ICOL = ICOL - LDRWRK
-            CALL DCOPY( NOBR2, DWORK(IREV), 1, DWORK(ICOL), 1 )
-   10    CONTINUE
-C
-         IF ( M.GT.0 )
-     $      CALL DLACPY( 'Full', NOBR2, M, U, LDU, DWORK(ICONN+NOBR2),
-     $                   LDRWRK )
-         CALL DLACPY( 'Full', NOBR2, L, Y, LDY,
-     $                DWORK(ICONN+LDRWRK*M+NOBR2), LDRWRK )
-      END IF
-C
-      IF ( M.GT.0 ) THEN
-C
-C        Let  Guu(i,j) = Guu0(i,j) + u_i*u_j' + u_(i+1)*u_(j+1)' +
-C                              ... + u_(i+NSM-1)*u_(j+NSM-1)',
-C        where  u_i'  is the i-th row of  U,  j = 1 : 2s,  i = 1 : j,
-C        NSM = NSMP - 2s,  and  Guu0(i,j)  is a zero matrix for
-C        BATCH = 'O' or 'F', and it is the matrix Guu(i,j) computed
-C        till the current block for BATCH = 'I' or 'L'. The matrix
-C        Guu(i,j)  is  m-by-m,  and  Guu(j,j)  is symmetric. The
-C        submatrices of the first block-row, Guu(1,j), are needed only.
-C
-C        Compute/update  Guu(1,1).
-C
-         IF( .NOT.FIRST .AND. CONNEC )
-     $      CALL DSYRK( 'Upper', 'Transpose', M, NOBR2, ONE,
-     $                  DWORK(ICONN), LDRWRK, UPD, DWORK(IPG), NRG )
-         CALL DSYRK( 'Upper', 'Transpose', M, NSM, ONE, U, LDU, UPD,
-     $               DWORK(IPG), NRG )
-         CALL MA02ED( 'Upper', M, DWORK(IPG), NRG )
-C
-         JD = 1
-C
-         IF( FIRST .OR. .NOT.CONNEC ) THEN
-C
-            DO 20 J = 2, NOBR2
-               JD = JD + M
-C
-C              Compute/update  Guu(1,j).
-C
-               CALL DGEMM( 'Transpose', 'NoTranspose', M, M, NSM, ONE,
-     $                     U, LDU, U(J,1), LDU, UPD,
-     $                     DWORK(IPG+(JD-1)*NRG), NRG )
-   20       CONTINUE
-C
-         ELSE
-C
-            DO 30 J = 2, NOBR2
-               JD = JD + M
-C
-C              Compute/update  Guu(1,j)  for sequential processing
-C              with connected blocks.
-C
-               CALL DGEMM( 'Transpose', 'NoTranspose', M, M, NOBR2,
-     $                     ONE, DWORK(ICONN), LDRWRK, DWORK(ICONN+J-1),
-     $                     LDRWRK, UPD, DWORK(IPG+(JD-1)*NRG), NRG )
-               CALL DGEMM( 'Transpose', 'NoTranspose', M, M, NSM, ONE,
-     $                     U, LDU, U(J,1), LDU, ONE,
-     $                     DWORK(IPG+(JD-1)*NRG), NRG )
-   30       CONTINUE
-C
-         END IF
-C
-C        Let  Guy(i,j) = Guy0(i,j) + u_i*y_j' + u_(i+1)*y_(j+1)' +
-C                              ... + u_(i+NSM-1)*y_(j+NSM-1)',
-C        where  u_i'  is the i-th row of  U,  y_j'  is the j-th row
-C        of  Y,  j = 1 : 2s,  i = 1 : 2s,  NSM = NSMP - 2s,  and
-C        Guy0(i,j)  is a zero matrix for  BATCH = 'O' or 'F', and it
-C        is the matrix Guy(i,j) computed till the current block for
-C        BATCH = 'I' or 'L'.  Guy(i,j) is m-by-L. The submatrices
-C        of the first block-row, Guy(1,j), as well as the transposes
-C        of the submatrices of the first block-column, i.e., Gyu(1,j),
-C        are needed only.
-C
-         JD = MMNOBR + 1
-C
-         IF( FIRST .OR. .NOT.CONNEC ) THEN
-C
-            DO 40 J = 1, NOBR2
-C
-C              Compute/update  Guy(1,j).
-C
-               CALL DGEMM( 'Transpose', 'NoTranspose', M, L, NSM, ONE,
-     $                     U, LDU, Y(J,1), LDY, UPD,
-     $                     DWORK(IPG+(JD-1)*NRG), NRG )
-               JD = JD + L
-   40       CONTINUE
-C
-         ELSE
-C
-            DO 50 J = 1, NOBR2
-C
-C              Compute/update  Guy(1,j)  for sequential processing
-C              with connected blocks.
-C
-               CALL DGEMM( 'Transpose', 'NoTranspose', M, L, NOBR2,
-     $                     ONE, DWORK(ICONN), LDRWRK,
-     $                     DWORK(ICONN+LDRWRK*M+J-1), LDRWRK, UPD,
-     $                     DWORK(IPG+(JD-1)*NRG), NRG )
-               CALL DGEMM( 'Transpose', 'NoTranspose', M, L, NSM, ONE,
-     $                     U, LDU, Y(J,1), LDY, ONE,
-     $                     DWORK(IPG+(JD-1)*NRG), NRG )
-               JD = JD + L
-   50       CONTINUE
-C
-         END IF
-C
-C        Now, the first M "positive" generators have been built.
-C        Transpose  Guy(1,1)  in the first block of the  Y  part of the
-C        "positive" generators.
-C
-         DO 60 J = 1, L
-            CALL DCOPY( M, DWORK(IPG+(MMNOBR+J-1)*NRG), 1,
-     $                  DWORK(IPY+J-1), NRG )
-   60    CONTINUE
-C
-         JD = 1
-C
-         IF( FIRST .OR. .NOT.CONNEC ) THEN
-C
-            DO 70 J = 2, NOBR2
-               JD = JD + M
-C
-C              Compute/update  Gyu(1,j).
-C
-               CALL DGEMM( 'Transpose', 'NoTranspose', L, M, NSM, ONE,
-     $                     Y, LDY, U(J,1), LDU, UPD,
-     $                     DWORK(IPY+(JD-1)*NRG), NRG )
-   70       CONTINUE
-C
-         ELSE
-C
-            DO 80 J = 2, NOBR2
-               JD = JD + M
-C
-C              Compute/update  Gyu(1,j)  for sequential processing
-C              with connected blocks.
-C
-               CALL DGEMM( 'Transpose', 'NoTranspose', L, M, NOBR2,
-     $                     ONE, DWORK(ICONN+LDRWRK*M), LDRWRK,
-     $                     DWORK(ICONN+J-1), LDRWRK, UPD,
-     $                     DWORK(IPY+(JD-1)*NRG), NRG )
-               CALL DGEMM( 'Transpose', 'NoTranspose', L, M, NSM, ONE,
-     $                     Y, LDY, U(J,1), LDU, ONE,
-     $                     DWORK(IPY+(JD-1)*NRG), NRG )
-   80       CONTINUE
-C
-         END IF
-C
-      END IF
-C
-C     Let  Gyy(i,j) = Gyy0(i,j) + y_i*y_i' + y_(i+1)*y_(i+1)' + ... +
-C                                 y_(i+NSM-1)*y_(i+NSM-1)',
-C     where  y_i'  is the i-th row of  Y,  j = 1 : 2s,  i = 1 : j,
-C     NSM = NSMP - 2s,  and  Gyy0(i,j)  is a zero matrix for
-C     BATCH = 'O' or 'F', and it is the matrix Gyy(i,j) computed till
-C     the current block for BATCH = 'I' or 'L'.  Gyy(i,j) is L-by-L,
-C     and  Gyy(j,j)  is symmetric. The submatrices of the first
-C     block-row, Gyy(1,j), are needed only.
-C
-      JD = MMNOBR + 1
-C
-C     Compute/update  Gyy(1,1).
-C
-      IF( .NOT.FIRST .AND. CONNEC )
-     $   CALL DSYRK( 'Upper', 'Transpose', L, NOBR2, ONE,
-     $               DWORK(ICONN+LDRWRK*M), LDRWRK, UPD,
-     $               DWORK(IPY+MMNOBR*NRG), NRG )
-      CALL DSYRK( 'Upper', 'Transpose', L, NSM, ONE, Y, LDY, UPD,
-     $            DWORK(IPY+MMNOBR*NRG), NRG )
-      CALL MA02ED( 'Upper', L, DWORK(IPY+MMNOBR*NRG), NRG )
-C
-      IF( FIRST .OR. .NOT.CONNEC ) THEN
-C
-         DO 90 J = 2, NOBR2
-            JD = JD + L
-C
-C           Compute/update  Gyy(1,j).
-C
-            CALL DGEMM( 'Transpose', 'NoTranspose', L, L, NSM, ONE, Y,
-     $                  LDY, Y(J,1), LDY, UPD, DWORK(IPY+(JD-1)*NRG),
-     $                  NRG )
-   90    CONTINUE
-C
-      ELSE
-C
-         DO 100 J = 2, NOBR2
-            JD = JD + L
-C
-C           Compute/update  Gyy(1,j)  for sequential processing with
-C           connected blocks.
-C
-            CALL DGEMM( 'Transpose', 'NoTranspose', L, L, NOBR2, ONE,
-     $                  DWORK(ICONN+LDRWRK*M), LDRWRK,
-     $                  DWORK(ICONN+LDRWRK*M+J-1), LDRWRK, UPD,
-     $                  DWORK(IPY+(JD-1)*NRG), NRG )
-            CALL DGEMM( 'Transpose', 'NoTranspose', L, L, NSM, ONE, Y,
-     $                  LDY, Y(J,1), LDY, ONE, DWORK(IPY+(JD-1)*NRG),
-     $                  NRG )
-  100    CONTINUE
-C
-      END IF
-C
-      IF ( .NOT.LAST ) THEN
-         IF ( FIRST ) THEN
-C
-C           For sequential processing, save the first 2*NOBR-1 rows of
-C           the first block of  U  and  Y  in the appropriate
-C           (M+L)*(2*NOBR-1) locations of  DWORK  starting at (1+M)*NRG.
-C           These will be used to construct the last negative generator.
-C
-            JD = NRG
-            IF ( M.GT.0 ) THEN
-               CALL DCOPY( M, DUM, 0, DWORK(JD), NRG )
-C
-               DO 110 J = 1, NOBR21
-                  JD = JD + MNRG
-                  CALL DCOPY( M, U(J,1), LDU, DWORK(JD), NRG )
-  110          CONTINUE
-C
-               JD = JD + MNRG
-            END IF
-            CALL DCOPY( L, DUM, 0, DWORK(JD), NRG )
-C
-            DO 120 J = 1, NOBR21
-               JD = JD + LNRG
-               CALL DCOPY( L, Y(J,1), LDY, DWORK(JD), NRG )
-  120       CONTINUE
-C
-         END IF
-C
-         IF ( CONNEC ) THEN
-C
-C           For sequential processing with connected data blocks,
-C           save the remaining ("connection") elements of  U  and  Y
-C           in (M+L)*2*NOBR locations of  DWORK  starting at ICONN.
-C
-            IF ( M.GT.0 )
-     $         CALL DLACPY( 'Full', NOBR2, M, U(NS,1), LDU,
-     $                      DWORK(ICONN), NOBR2 )
-            CALL DLACPY( 'Full', NOBR2, L, Y(NS,1), LDY,
-     $                   DWORK(ICONN+MMNOBR), NOBR2 )
-         END IF
-C
-C        Return to get new data.
-C
-         ICYCLE = ICYCLE + 1
-         IF ( ICYCLE.GT.MAXCYC )
-     $      IWARN = 1
-         RETURN
-      END IF
-C
-      IF ( LAST ) THEN
-C
-C        Try to compute the R factor.
-C
-C        Scale the first M+L positive generators and set the first
-C        M+L negative generators.
-C        Workspace: need   (M+L)*4*NOBR*(M+L+1)+M+L.
-C
-         JWORK = NRG*2*NR + 1
-         CALL DCOPY( M, DWORK(IPG), NRG+1, DWORK(JWORK), 1 )
-         CALL DCOPY( L, DWORK(IPY+MMNOBR*NRG), NRG+1, DWORK(JWORK+M),
-     $               1 )
-C
-         DO 130 I = 1, M + L
-            IWORK(I) = IDAMAX( M+L, DWORK(JWORK), 1 )
-            DWORK(JWORK+IWORK(I)-1) = ZERO
-  130    CONTINUE
-C
-         DO 150 I = 1, M + L
-            IMAX = IWORK(I)
-            IF ( IMAX.LE.M ) THEN
-               ICOL = IMAX
-            ELSE
-               ICOL = MMNOBR - M + IMAX
-            END IF
-            BETA = SQRT( ABS( DWORK(IPG+IMAX-1+(ICOL-1)*NRG) ) )
-            IF ( BETA.EQ.ZERO ) THEN
-C
-C              Error exit.
-C
-               INFO = 1
-               RETURN
-            END IF
-            CALL DSCAL( NR, ONE / BETA, DWORK(IPG+IMAX-1), NRG )
-            CALL DCOPY( NR, DWORK(IPG+IMAX-1), NRG, DWORK(ING+IMAX-1),
-     $                  NRG )
-            DWORK(IPG+IMAX-1+(ICOL-1)*NRG) = BETA
-            DWORK(ING+IMAX-1+(ICOL-1)*NRG) = ZERO
-C
-            DO 140 J = I + 1, M + L
-               DWORK(IPG+IWORK(J)-1+(ICOL-1)*NRG) = ZERO
-  140       CONTINUE
-C
-  150    CONTINUE
-C
-C        Compute the last two generators.
-C
-         IF ( .NOT.FIRST ) THEN
-C
-C           For sequential processing, move the stored last negative
-C           generator.
-C
-            CALL DCOPY( NR, DWORK(NRG), NRG, DWORK(ING+NRG-1), NRG )
-         END IF
-C
-         JD = NRG
-         IF ( M.GT.0 ) THEN
-C
-            DO 160 J = NS, NSMP
-               CALL DCOPY( M, U(J,1), LDU, DWORK(JD), NRG )
-               JD = JD + MNRG
-  160       CONTINUE
-C
-         END IF
-C
-         DO 170 J = NS, NSMP
-            CALL DCOPY( L, Y(J,1), LDY, DWORK(JD), NRG )
-            JD = JD + LNRG
-  170    CONTINUE
-C
-         IF ( FIRST ) THEN
-            IF ( M.GT.0 ) THEN
-               CALL DCOPY( M, DUM, 0, DWORK(JD), NRG )
-C
-               DO 180 J = 1, NOBR21
-                  JD = JD + MNRG
-                  CALL DCOPY( M, U(J,1), LDU, DWORK(JD), NRG )
-  180          CONTINUE
-C
-               JD = JD + MNRG
-            END IF
-            CALL DCOPY( L, DUM, 0, DWORK(JD), NRG )
-C
-            DO 190 J = 1, NOBR21
-               JD = JD + LNRG
-               CALL DCOPY( L, Y(J,1), LDY, DWORK(JD), NRG )
-  190       CONTINUE
-C
-         END IF
-C
-         ITAU = JWORK
-         IPGC = IPG + MMNOBR*NRG
-C
-         IF ( M.GT.0 ) THEN
-C
-C           Process the input part of the generators.
-C
-            JWORK = ITAU + M
-C
-C           Reduce the first M columns of the matrix G1 of positive
-C           generators to an upper triangular form.
-C           Workspace: need   (M+L)*4*NOBR*(M+L+1)+2*M;
-C                   prefer (M+L)*4*NOBR*(M+L+1)+M+M*NB.
-C
-            INGC = ING
-            CALL DGEQRF( NRG, M, DWORK(IPG), NRG, DWORK(ITAU),
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C           Workspace: need   (M+L)*4*NOBR*(M+L+1)+(M+L)*2*NOBR;
-C                      prefer (M+L)*4*NOBR*(M+L+1)+M+
-C                                                 ((M+L)*2*NOBR-M)*NB.
-C
-            CALL DORMQR( 'Left', 'Transpose', NRG, NR-M, M, DWORK(IPG),
-     $                   NRG, DWORK(ITAU), DWORK(IPG+MNRG), NRG,
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C           Annihilate, column by column, the first M columns of the
-C           matrix G2 of negative generators, using Householder
-C           transformations and modified hyperbolic plane rotations.
-C           In the DLARF calls, ITAU is a pointer to the workspace
-C           array.
-C
-            DO 210 J = 1, M
-               CALL DLARFG( NRG, DWORK(INGC), DWORK(INGC+1), 1, TAU )
-               BETA = DWORK(INGC)
-               DWORK(INGC) = ONE
-               INGP = INGC + NRG
-               CALL DLARF( 'Left', NRG, NR-J, DWORK(INGC), 1, TAU,
-     $                     DWORK(INGP), NRG, DWORK(ITAU) )
-               DWORK(INGC) = BETA
-C
-C              Compute the coefficients of the modified hyperbolic
-C              rotation.
-C
-               CALL MA02FD( DWORK(IPG+(J-1)*(NRG+1)), DWORK(INGC), CS,
-     $                      SN, IERR )
-               IF( IERR.NE.0 ) THEN
-C
-C                 Error return: the matrix H'*H is not (numerically)
-C                 positive definite.
-C
-                  INFO = 1
-                  RETURN
-               END IF
-C
-               DO 200 I = J*NRG, ( NR - 1 )*NRG, NRG
-                  DWORK(IPG+J-1+I) =     ( DWORK(IPG+J-1+I) -
-     $                                SN * DWORK(ING+I) ) / CS
-                  DWORK(ING+I)     = -SN * DWORK(IPG+J-1+I) +
-     $                                CS * DWORK(ING+I)
-  200          CONTINUE
-C
-               INGC = INGP
-  210       CONTINUE
-C
-C           Save one block row of R, and shift the generators for the
-C           calculation of the following row.
-C
-            CALL DLACPY( 'Upper', M, NR, DWORK(IPG), NRG, R, LDR )
-C
-            DO 220 I = ( MMNOBR - M )*NRG, MNRG, -MNRG
-               CALL DLACPY( 'Full', M, M, DWORK(IPG+I-MNRG), NRG,
-     $                      DWORK(IPG+I), NRG )
-  220       CONTINUE
-C
-            DO 230 I = ( NR - L )*NRG, ( MMNOBR + L )*NRG, -LNRG
-               CALL DLACPY( 'Full', M, L, DWORK(IPG+I-LNRG), NRG,
-     $                      DWORK(IPG+I), NRG )
-  230       CONTINUE
-C
-            CALL DLASET( 'Full', M, L, ZERO, ZERO, DWORK(IPGC), NRG )
-C
-C           Update the input part of generators using Schur algorithm.
-C           Workspace: need   (M+L)*4*NOBR*(M+L+1)+2*NOBR*(M+L)-M.
-C
-            JDS  = MNRG
-            ICOL = M
-C
-            DO 280 K = 2, NOBR2
-               CALL MB04OD( 'Full', M, NR-ICOL-M, L+1, DWORK(IPG+JDS),
-     $                      NRG, DWORK(IPY+JDS), NRG,
-     $                      DWORK(IPG+JDS+MNRG), NRG,
-     $                      DWORK(IPY+JDS+MNRG), NRG, DWORK(ITAU),
-     $                      DWORK(JWORK) )
-C
-               DO 250 J = 1, M
-                  ICJ = ICOL + J
-                  CALL DLARFG( NRG, DWORK(INGC), DWORK(INGC+1), 1, TAU )
-                  BETA = DWORK(INGC)
-                  DWORK(INGC) = ONE
-                  INGP = INGC + NRG
-                  CALL DLARF( 'Left', NRG, NR-ICJ, DWORK(INGC), 1, TAU,
-     $                        DWORK(INGP), NRG, DWORK(ITAU) )
-                  DWORK(INGC) = BETA
-C
-C                 Compute the coefficients of the modified hyperbolic
-C                 rotation.
-C
-                  CALL MA02FD( DWORK(IPG+J-1+(ICJ-1)*NRG), DWORK(INGC),
-     $                         CS, SN, IERR )
-                  IF( IERR.NE.0 ) THEN
-C
-C                    Error return: the matrix H'*H is not (numerically)
-C                    positive definite.
-C
-                     INFO = 1
-                     RETURN
-                  END IF
-C
-                  DO 240 I = ICJ*NRG, ( NR - 1 )*NRG, NRG
-                     DWORK(IPG+J-1+I) =     ( DWORK(IPG+J-1+I) -
-     $                                   SN * DWORK(ING+I) ) / CS
-                     DWORK(ING+I)     = -SN * DWORK(IPG+J-1+I) +
-     $                                   CS * DWORK(ING+I)
-  240             CONTINUE
-C
-                  INGC = INGP
-  250          CONTINUE
-C
-C              Save one block row of R, and shift the generators for the
-C              calculation of the following row.
-C
-               CALL DLACPY( 'Upper', M, NR-ICOL, DWORK(IPG+JDS), NRG,
-     $                      R(ICOL+1,ICOL+1), LDR )
-               ICOL = ICOL + M
-C
-               DO 260 I = ( MMNOBR - M )*NRG, ICOL*NRG, -MNRG
-                  CALL DLACPY( 'Full', M, M, DWORK(IPG+I-MNRG), NRG,
-     $                         DWORK(IPG+I), NRG )
-  260          CONTINUE
-C
-               DO 270 I = ( NR - L )*NRG, ( MMNOBR + L )*NRG, -LNRG
-                  CALL DLACPY( 'Full', M, L, DWORK(IPG+I-LNRG), NRG,
-     $                         DWORK(IPG+I), NRG )
-  270          CONTINUE
-C
-               CALL DLASET( 'Full', M, L, ZERO, ZERO, DWORK(IPGC), NRG )
-               JDS = JDS + MNRG
-  280       CONTINUE
-C
-         END IF
-C
-C        Process the output part of the generators.
-C
-         JWORK = ITAU + L
-C
-C        Reduce the first L columns of the submatrix
-C        G1(1:M+L+1,2*M*NOBR+1:2*(M+L)*NOBR) to upper triangular form.
-C        Workspace: need   (M+L)*4*NOBR*(M+L+1)+2*L;
-C                   prefer (M+L)*4*NOBR*(M+L+1)+L+L*NB.
-C
-         INGC = ING + MMNOBR*NRG
-         CALL DGEQRF( NRG, L, DWORK(IPGC), NRG, DWORK(ITAU),
-     $                DWORK(JWORK), LDWORK-JWORK+1, IERR )
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C        Workspace: need   (M+L)*4*NOBR*(M+L+1)+L*2*NOBR;
-C                   prefer (M+L)*4*NOBR*(M+L+1)+L+(L*2*NOBR-L)*NB.
-C
-         CALL DORMQR( 'Left', 'Transpose', NRG, LLNOBR-L, L,
-     $                DWORK(IPGC), NRG, DWORK(ITAU), DWORK(IPGC+LNRG),
-     $                NRG, DWORK(JWORK), LDWORK-JWORK+1, IERR )
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C        Annihilate, column by column, the first L columns of the
-C        output part of the matrix G2 of negative generators, using
-C        Householder transformations and modified hyperbolic rotations.
-C
-         DO 300 J = 1, L
-            CALL DLARFG( NRG, DWORK(INGC), DWORK(INGC+1), 1, TAU )
-            BETA = DWORK(INGC)
-            DWORK(INGC) = ONE
-            INGP = INGC + NRG
-            CALL DLARF( 'Left', NRG, LLNOBR-J, DWORK(INGC), 1, TAU,
-     $                  DWORK(INGP), NRG, DWORK(ITAU) )
-            DWORK(INGC) = BETA
-C
-C           Compute the coefficients of the modified hyperbolic
-C           rotation.
-C
-            CALL MA02FD( DWORK(IPGC+(J-1)*(NRG+1)), DWORK(INGC), CS, SN,
-     $                   IERR )
-            IF( IERR.NE.0 ) THEN
-C
-C              Error return: the matrix H'*H is not (numerically)
-C              positive definite.
-C
-               INFO = 1
-               RETURN
-            END IF
-C
-            DO 290 I = ( J + MMNOBR )*NRG, ( NR - 1 )*NRG, NRG
-               DWORK(IPG+J-1+I) =     ( DWORK(IPG+J-1+I) -
-     $                             SN * DWORK(ING+I) ) / CS
-               DWORK(ING+I)     = -SN * DWORK(IPG+J-1+I) +
-     $                             CS * DWORK(ING+I)
-  290       CONTINUE
-C
-            INGC = INGP
-  300    CONTINUE
-C
-C        Save one block row of R, and shift the generators for the
-C        calculation of the following row.
-C
-         CALL DLACPY( 'Upper', L, LLNOBR, DWORK(IPGC), NRG,
-     $                 R(MMNOBR+1,MMNOBR+1), LDR )
-C
-         DO 310 I = ( NR - L )*NRG, ( MMNOBR + L )*NRG, -LNRG
-            CALL DLACPY( 'Full', L, L, DWORK(IPG+I-LNRG), NRG,
-     $                   DWORK(IPG+I), NRG )
-  310    CONTINUE
-C
-C        Update the output part of generators using the Schur algorithm.
-C        Workspace: need   (M+L)*4*NOBR*(M+L+1)+2*NOBR*L-L.
-C
-         JDS  = LNRG
-         ICOL = L
-C
-         DO 350 K = 2, NOBR2
-            CALL MB04OD( 'Full', L, LLNOBR-ICOL-L, M+1, DWORK(IPGC+JDS),
-     $                   NRG, DWORK(IPGC+L+JDS), NRG,
-     $                   DWORK(IPGC+JDS+LNRG),   NRG,
-     $                   DWORK(IPGC+L+JDS+LNRG), NRG, DWORK(ITAU),
-     $                   DWORK(JWORK) )
-C
-            DO 330 J = 1, L
-               ICJ = ICOL + J
-               CALL DLARFG( NRG, DWORK(INGC), DWORK(INGC+1), 1, TAU )
-               BETA = DWORK(INGC)
-               DWORK(INGC) = ONE
-               INGP = INGC + NRG
-               CALL DLARF( 'Left', NRG, LLNOBR-ICJ, DWORK(INGC), 1,
-     $                     TAU, DWORK(INGP), NRG, DWORK(ITAU) )
-               DWORK(INGC) = BETA
-C
-C              Compute the coefficients of the modified hyperbolic
-C              rotation.
-C
-               CALL MA02FD( DWORK(IPGC+J-1+(ICJ-1)*NRG), DWORK(INGC),
-     $                      CS, SN, IERR )
-               IF( IERR.NE.0 ) THEN
-C
-C                 Error return: the matrix H'*H is not (numerically)
-C                 positive definite.
-C
-                  INFO = 1
-                  RETURN
-               END IF
-C
-               DO 320 I = ( ICJ + MMNOBR )*NRG, ( NR - 1 )*NRG, NRG
-                  DWORK(IPG+J-1+I) =     ( DWORK(IPG+J-1+I) -
-     $                                SN * DWORK(ING+I) ) / CS
-                  DWORK(ING+I)     = -SN * DWORK(IPG+J-1+I) +
-     $                                CS * DWORK(ING+I)
-  320          CONTINUE
-C
-               INGC = INGP
-  330       CONTINUE
-C
-C           Save one block row of R, and shift the generators for the
-C           calculation of the following row.
-C
-            CALL DLACPY( 'Upper', L, LLNOBR-ICOL, DWORK(IPGC+JDS), NRG,
-     $                    R(MMNOBR+ICOL+1,MMNOBR+ICOL+1), LDR )
-C
-            DO 340 I = ( NR - L )*NRG, ( MMNOBR + ICOL )*NRG, -LNRG
-               CALL DLACPY( 'Full', L, L, DWORK(IPG+I-LNRG), NRG,
-     $                      DWORK(IPG+I), NRG )
-  340       CONTINUE
-C
-            ICOL = ICOL + L
-            JDS  = JDS + LNRG
-  350    CONTINUE
-C
-         IF ( MOESP .AND. M.GT.0 ) THEN
-C
-C           For the MOESP algorithm, interchange the past and future
-C           input parts of the R factor, and compute the new R factor
-C           using a specialized QR factorization.  A tailored fast
-C           QR factorization for the MOESP algorithm could be slightly
-C           more efficient.
-C
-            DO 360 J = 1, MNOBR
-               CALL DSWAP( J, R(1,J), 1, R(1,MNOBR+J), 1 )
-               CALL DCOPY( MNOBR, R(J+1,MNOBR+J), 1, R(J+1,J), 1 )
-               CALL DCOPY( MMNOBR-J, DUM, 0, R(J+1,MNOBR+J), 1 )
-  360       CONTINUE
-C
-C           Triangularize the first two block columns (using structure),
-C           and apply the transformation to the corresponding part of
-C           the remaining block columns.
-C           Workspace: need 2*(M+L)*NOBR.
-C
-            ITAU  = 1
-            JWORK = ITAU + MMNOBR
-            CALL MB04ID( MMNOBR, MMNOBR, MNOBR-1, LLNOBR, R, LDR,
-     $                   R(1,MMNOBR+1), LDR, DWORK(ITAU),
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-         END IF
-      END IF
-C
-      NSMPSM = 0
-      ICYCLE = 1
-C
-C     Return optimal workspace in  DWORK(1).
-C
-      DWORK( 1 ) = MAXWRK
-      MAXWRK = 1
-      RETURN
-C
-C *** Last line of IB01MY ***
-      END
--- a/extra/control-devel/src/IB01ND.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,731 +0,0 @@
-      SUBROUTINE IB01ND( METH, JOBD, NOBR, M, L, R, LDR, SV, TOL, IWORK,
-     $                   DWORK, LDWORK, IWARN, 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 find the singular value decomposition (SVD) giving the system
-C     order, using the triangular factor of the concatenated block
-C     Hankel matrices. Related preliminary calculations needed for
-C     computing the system matrices are also performed.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     METH    CHARACTER*1
-C             Specifies the subspace identification method to be used,
-C             as follows:
-C             = 'M':  MOESP  algorithm with past inputs and outputs;
-C             = 'N':  N4SID  algorithm.
-C
-C     JOBD    CHARACTER*1
-C             Specifies whether or not the matrices B and D should later
-C             be computed using the MOESP approach, as follows:
-C             = 'M':  the matrices B and D should later be computed
-C                     using the MOESP approach;
-C             = 'N':  the matrices B and D should not be computed using
-C                     the MOESP approach.
-C             This parameter is not relevant for METH = 'N'.
-C
-C     Input/Output Parameters
-C
-C     NOBR    (input) INTEGER
-C             The number of block rows,  s,  in the input and output
-C             block Hankel matrices.  NOBR > 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension
-C             ( LDR,2*(M+L)*NOBR )
-C             On entry, the leading 2*(M+L)*NOBR-by-2*(M+L)*NOBR upper
-C             triangular part of this array must contain the upper
-C             triangular factor R from the QR factorization of the
-C             concatenated block Hankel matrices. Denote  R_ij,
-C             i,j = 1:4,  the ij submatrix of  R,  partitioned by
-C             M*NOBR,  M*NOBR,  L*NOBR,  and  L*NOBR  rows and columns.
-C             On exit, if INFO = 0, the leading
-C             2*(M+L)*NOBR-by-2*(M+L)*NOBR upper triangular part of this
-C             array contains the matrix S, the processed upper
-C             triangular factor R, as required by other subroutines.
-C             Specifically, let  S_ij, i,j = 1:4,  be the ij submatrix
-C             of  S,  partitioned by  M*NOBR,  L*NOBR,  M*NOBR,  and
-C             L*NOBR  rows and columns. The submatrix  S_22  contains
-C             the matrix of left singular vectors needed subsequently.
-C             Useful information is stored in  S_11  and in the
-C             block-column  S_14 : S_44.  For METH = 'M' and JOBD = 'M',
-C             the upper triangular part of  S_31  contains the upper
-C             triangular factor in the QR factorization of the matrix
-C             R_1c = [ R_12'  R_22'  R_11' ]',  and  S_12  contains the
-C             corresponding leading part of the transformed matrix
-C             R_2c = [ R_13'  R_23'  R_14' ]'.  For  METH = 'N',  the
-C             subarray  S_41 : S_43  contains the transpose of the
-C             matrix contained in  S_14 : S_34.
-C
-C     LDR     INTEGER
-C             The leading dimension of the array  R.
-C             LDR >= MAX( 2*(M+L)*NOBR, 3*M*NOBR ),
-C                                  for METH = 'M' and JOBD = 'M';
-C             LDR >= 2*(M+L)*NOBR, for METH = 'M' and JOBD = 'N' or
-C                                  for METH = 'N'.
-C
-C     SV      (output) DOUBLE PRECISION array, dimension ( L*NOBR )
-C             The singular values of the relevant part of the triangular
-C             factor from the QR factorization of the concatenated block
-C             Hankel matrices.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used for estimating the rank of
-C             matrices. If the user sets  TOL > 0,  then the given value
-C             of  TOL  is used as a lower bound for the reciprocal
-C             condition number;  an m-by-n matrix whose estimated
-C             condition number is less than  1/TOL  is considered to
-C             be of full rank.  If the user sets  TOL <= 0,  then an
-C             implicitly computed, default tolerance, defined by
-C             TOLDEF = m*n*EPS,  is used instead, where  EPS  is the
-C             relative machine precision (see LAPACK Library routine
-C             DLAMCH).
-C             This parameter is not used for  METH = 'M'.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension ((M+L)*NOBR)
-C             This parameter is not referenced for METH = 'M'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of LDWORK,  and, for  METH = 'N',  DWORK(2)  and  DWORK(3)
-C             contain the reciprocal condition numbers of the
-C             triangular factors of the matrices  U_f  and  r_1  [6].
-C             On exit, if  INFO = -12,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= max( (2*M-1)*NOBR, (M+L)*NOBR, 5*L*NOBR ),
-C                                         if METH = 'M' and JOBD = 'M';
-C             LDWORK >=  5*L*NOBR,        if METH = 'M' and JOBD = 'N';
-C             LDWORK >=  5*(M+L)*NOBR+1,  if METH = 'N'.
-C             For good performance,  LDWORK  should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 4:  the least squares problems with coefficient matrix
-C                   U_f,  used for computing the weighted oblique
-C                   projection (for METH = 'N'), have a rank-deficient
-C                   coefficient matrix;
-C             = 5:  the least squares problem with coefficient matrix
-C                   r_1  [6], used for computing the weighted oblique
-C                   projection (for METH = 'N'), has a rank-deficient
-C                   coefficient matrix.
-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             = 2:  the singular value decomposition (SVD) algorithm did
-C                   not converge.
-C
-C     METHOD
-C
-C     A singular value decomposition (SVD) of a certain matrix is
-C     computed, which reveals the order  n  of the system as the number
-C     of "non-zero" singular values. For the MOESP approach, this matrix
-C     is  [ R_24'  R_34' ]' := R(ms+1:(2m+l)s,(2m+l)s+1:2(m+l)s),
-C     where  R  is the upper triangular factor  R  constructed by SLICOT
-C     Library routine  IB01MD.  For the N4SID approach, a weighted
-C     oblique projection is computed from the upper triangular factor  R
-C     and its SVD is then found.
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Dewilde, P.
-C         Subspace Model Identification. Part 1: The output-error
-C         state-space model identification class of algorithms.
-C         Int. J. Control, 56, pp. 1187-1210, 1992.
-C
-C     [2] Verhaegen M.
-C         Subspace Model Identification. Part 3: Analysis of the
-C         ordinary output-error state-space model identification
-C         algorithm.
-C         Int. J. Control, 58, pp. 555-586, 1993.
-C
-C     [3] Verhaegen M.
-C         Identification of the deterministic part of MIMO state space
-C         models given in innovations form from input-output data.
-C         Automatica, Vol.30, No.1, pp.61-74, 1994.
-C
-C     [4] Van Overschee, P., and De Moor, B.
-C         N4SID: Subspace Algorithms for the Identification of
-C         Combined Deterministic-Stochastic Systems.
-C         Automatica, Vol.30, No.1, pp. 75-93, 1994.
-C
-C     [5] Van Overschee, P., and De Moor, B.
-C         Subspace Identification for Linear Systems: Theory -
-C         Implementation - Applications.
-C         Kluwer Academic Publishers, Boston/London/Dordrecht, 1996.
-C
-C     [6] Sima, V.
-C         Subspace-based Algorithms for Multivariable System
-C         Identification.
-C         Studies in Informatics and Control, 5, pp. 335-344, 1996.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is numerically stable.
-C                                      3
-C     The algorithm requires 0(((m+l)s) ) floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 1999.
-C
-C     REVISIONS
-C
-C     Feb. 2000, Feb. 2001, Feb. 2004, March 2005.
-C
-C     KEYWORDS
-C
-C     Identification methods, multivariable systems, QR decomposition,
-C     singular value decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, THREE
-      PARAMETER          ( ZERO  = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
-     $                     THREE = 3.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   TOL
-      INTEGER            INFO, IWARN, L, LDR, LDWORK, M, NOBR
-      CHARACTER          JOBD, METH
-C     .. Array Arguments ..
-      DOUBLE PRECISION   DWORK(*), R(LDR, *), SV(*)
-      INTEGER            IWORK(*)
-C     .. Local Scalars ..
-      DOUBLE PRECISION   EPS, RCOND1, RCOND2, SVLMAX, THRESH, TOLL
-      INTEGER            I, IERR, ITAU, ITAU2, ITAU3, J, JWORK, LLMNOB,
-     $                   LLNOBR, LMMNOB, LMNOBR, LNOBR, MAXWRK, MINWRK,
-     $                   MMNOBR, MNOBR, NR, NR2, NR3, NR4, NRSAVE, RANK,
-     $                   RANK1
-      LOGICAL            JOBDM, MOESP, N4SID
-C     .. Local Arrays ..
-      DOUBLE PRECISION   DUM(1), SVAL(3)
-C     .. External Functions ..
-      LOGICAL            LSAME
-      INTEGER            ILAENV
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           DLAMCH, ILAENV, LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DCOPY, DGEQRF, DLACPY, DLASET, DORMQR, DSWAP,
-     $                   DTRCON, MA02AD, MB03OD, MB03UD, MB04ID, MB04IY,
-     $                   MB04OD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          INT, MAX
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode the scalar input parameters.
-C
-      MOESP  = LSAME( METH, 'M' )
-      N4SID  = LSAME( METH, 'N' )
-      JOBDM  = LSAME( JOBD, 'M' )
-      MNOBR  = M*NOBR
-      LNOBR  = L*NOBR
-      LLNOBR = LNOBR + LNOBR
-      LMNOBR = LNOBR + MNOBR
-      MMNOBR = MNOBR + MNOBR
-      LMMNOB = MMNOBR + LNOBR
-      NR     = LMNOBR + LMNOBR
-      IWARN  = 0
-      INFO   = 0
-C
-C     Check the scalar input parameters.
-C
-      IF( .NOT.( MOESP .OR. N4SID ) ) THEN
-         INFO = -1
-      ELSE IF( MOESP .AND. .NOT.( JOBDM .OR. LSAME( JOBD, 'N' ) ) ) THEN
-         INFO = -2
-      ELSE IF( NOBR.LE.0 ) THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( L.LE.0 ) THEN
-         INFO = -5
-      ELSE IF( LDR.LT.NR .OR. ( MOESP .AND. JOBDM .AND.
-     $         LDR.LT.3*MNOBR ) ) THEN
-         INFO = -7
-      ELSE
-C
-C        Compute workspace.
-C        (Note: Comments in the code beginning "Workspace:" describe the
-C         minimal amount of workspace needed at that point in the code,
-C         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
-         MINWRK = 1
-         IF ( LDWORK.GE.1 ) THEN
-            IF ( MOESP ) THEN
-               MINWRK = 5*LNOBR
-               IF ( JOBDM )
-     $            MINWRK = MAX( MMNOBR - NOBR, LMNOBR, MINWRK )
-               MAXWRK = LNOBR + LNOBR*ILAENV( 1, 'DGEQRF', ' ', LMNOBR,
-     $                                        LNOBR, -1, -1 )
-            ELSE
-C
-               MINWRK = MAX( MINWRK, 5*LMNOBR + 1 )
-               MAXWRK = MAX( MNOBR + MNOBR*ILAENV( 1, 'DGEQRF', ' ',
-     $                                 MMNOBR, MNOBR, -1, -1 ),
-     $                       MNOBR + LLNOBR*ILAENV( 1, 'DORMQR', 'LT',
-     $                                 MMNOBR, LLNOBR, MNOBR, -1 ) )
-               MAXWRK = MAX( MAXWRK, MNOBR + LNOBR*ILAENV( 1, 'DORMQR',
-     $                                 'LN', MMNOBR, LNOBR, MNOBR,
-     $                                 -1 ) )
-               MAXWRK = MAX( MAXWRK, LNOBR + LNOBR*ILAENV( 1, 'DGEQRF',
-     $                                  ' ', LMMNOB, LNOBR, -1, -1 ) )
-            END IF
-            MAXWRK = MAX( MINWRK, MAXWRK )
-         END IF
-C
-         IF( LDWORK.LT.MINWRK ) THEN
-            INFO = -12
-            DWORK( 1 ) = MINWRK
-         END IF
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01ND', -INFO )
-         RETURN
-      END IF
-C
-C     Compute pointers to the needed blocks of  R.
-C
-      NR2   = MNOBR  + 1
-      NR3   = MMNOBR + 1
-      NR4   = LMMNOB + 1
-      ITAU  = 1
-      JWORK = ITAU + MNOBR
-C
-      IF( MOESP ) THEN
-C
-C        MOESP approach.
-C
-         IF( M.GT.0 .AND. JOBDM ) THEN
-C
-C           Rearrange the blocks of  R:
-C           Copy the (1,1) block into the position (3,2) and
-C           copy the (1,4) block into (3,3).
-C
-            CALL DLACPY( 'Upper', MNOBR, MNOBR, R, LDR, R(NR3,NR2),
-     $                   LDR )
-            CALL DLACPY( 'Full',  MNOBR, LNOBR, R(1,NR4), LDR,
-     $                   R(NR3,NR3), LDR )
-C
-C           Using structure, triangularize the matrix
-C              R_1c = [ R_12'  R_22'  R_11' ]'
-C           and then apply the transformations to the matrix
-c              R_2c = [ R_13'  R_23'  R_14' ]'.
-C           Workspace: need M*NOBR + MAX(M-1,L)*NOBR.
-C
-            CALL MB04OD( 'Upper', MNOBR, LNOBR, MNOBR, R(NR2,NR2), LDR,
-     $                   R(NR3,NR2), LDR, R(NR2,NR3), LDR, R(NR3,NR3),
-     $                   LDR, DWORK(ITAU), DWORK(JWORK) )
-            CALL MB04ID( MMNOBR, MNOBR, MNOBR-1, LNOBR, R(1,NR2), LDR,
-     $                   R(1,NR3), LDR, DWORK(ITAU), DWORK(JWORK),
-     $                   LDWORK-JWORK+1, IERR )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C           Copy the leading  M*NOBR x M*NOBR  and  M*NOBR x L*NOBR
-C           submatrices of  R_1c  and  R_2c,  respectively, into their
-C           final positions, required by SLICOT Library routine  IB01PD.
-C
-            CALL DLACPY( 'Upper', MNOBR, MNOBR, R(1,NR2), LDR,
-     $                   R(LMNOBR+1,1), LDR )
-            CALL DLACPY( 'Full',  MNOBR, LNOBR, R(1,NR3), LDR, R(1,NR2),
-     $                   LDR )
-         END IF
-C
-C        Copy [ R_24'  R_34' ]'  in  [ R_22'  R_32' ]'.
-C
-         CALL DLACPY( 'Full', LMNOBR, LNOBR, R(NR2,NR4), LDR,
-     $                R(NR2,NR2), LDR )
-C
-C        Triangularize the matrix in  [ R_22'  R_32' ]'.
-C        Workspace: need 2*L*NOBR; prefer L*NOBR + L*NOBR*NB.
-C
-         JWORK = ITAU + LNOBR
-         CALL DGEQRF( LMNOBR, LNOBR, R(NR2,NR2), LDR, DWORK(ITAU),
-     $                DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-      ELSE
-C
-C        N4SID approach.
-C
-         DUM(1) = ZERO
-         LLMNOB = LLNOBR + MNOBR
-C
-C        Set the precision parameters. A threshold value  EPS**(2/3)  is
-C        used for deciding to use pivoting or not, where  EPS  is the
-C        relative machine precision (see LAPACK Library routine DLAMCH).
-C
-         TOLL   = TOL
-         EPS    = DLAMCH( 'Precision' )
-         THRESH = EPS**( TWO/THREE )
-C
-         IF( M.GT.0 ) THEN
-C
-C           For efficiency of later calculations, interchange the first
-C           two block-columns. The corresponding submatrices are
-C           redefined according to their new position.
-C
-            DO 10 I = 1, MNOBR
-               CALL DSWAP( I, R(1,I), 1, R(1,MNOBR+I), 1 )
-               CALL DCOPY( MNOBR, R(I+1,MNOBR+I), 1, R(I+1,I), 1 )
-               CALL DCOPY( MMNOBR-I, DUM, 0, R(I+1,MNOBR+I), 1 )
-   10       CONTINUE
-C
-C           Now,
-C
-C           U_f = [ R_11'  R_21'    0      0   ]',
-C           U_p = [ R_12'    0      0      0   ]',
-C           Y_p = [ R_13'  R_23'  R_33'    0   ]',  and
-C           Y_f = [ R_14'  R_24'  R_34'  R_44' ]',
-C
-C           where  R_21,  R_12,  R_33,  and  R_44  are upper triangular.
-C           Define  W_p := [ U_p  Y_p ].
-C
-C           Prepare the computation of residuals of the two least
-C           squares problems giving the weighted oblique projection P:
-C
-C           r_1 = W_p - U_f X_1,   X_1 = arg min || U_f X - W_p ||,
-C           r_2 = Y_f - U_f X_2,   X_2 = arg min || U_f X - Y_f ||,
-C
-C           P = (arg min || r_1 X - r_2 ||)' r_1'.                   (1)
-C
-C           Alternately,  P'  is given by the projection
-C              P' = Q_1 (Q_1)' r_2,
-C           where  Q_1  contains the first  k  columns of the orthogonal
-C           matrix in the  QR  factorization of  r_1,  k := rank(r_1).
-C
-C           Triangularize the matrix  U_f = q r  (using structure), and
-C           apply the transformation  q'  to the corresponding part of
-C           the matrices  W_p,  and  Y_f.
-C           Workspace: need 2*(M+L)*NOBR.
-C
-            CALL MB04ID( MMNOBR, MNOBR, MNOBR-1, LLMNOB, R, LDR,
-     $                   R(1,NR2), LDR, DWORK(ITAU), DWORK(JWORK),
-     $                   LDWORK-JWORK+1, IERR )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C           Save updated  Y_f  (transposed) in the last block-row of  R.
-C
-            CALL MA02AD( 'Full', LMMNOB, LNOBR, R(1,NR4), LDR, R(NR4,1),
-     $                   LDR )
-C
-C           Check the condition of the triangular factor  r  and decide
-C           to use pivoting or not.
-C           Workspace: need 4*M*NOBR.
-C
-            CALL DTRCON( '1-norm', 'Upper', 'NonUnit', MNOBR, R, LDR,
-     $                   RCOND1, DWORK(JWORK), IWORK, IERR )
-C
-            IF( TOLL.LE.ZERO )
-     $         TOLL = MNOBR*MNOBR*EPS
-            IF ( RCOND1.GT.MAX( TOLL, THRESH ) ) THEN
-C
-C              U_f is considered full rank and no pivoting is used.
-C
-               CALL DLASET( 'Full', MNOBR, LLMNOB, ZERO, ZERO, R(1,NR2),
-     $                      LDR )
-            ELSE
-C
-C              Save information about  q  in the (2,1) block of  R.
-C              Use QR factorization with column pivoting,  r P = Q R.
-C              Information on  Q  is stored in the strict lower triangle
-C              of R_11  and in  DWORK(ITAU2).
-C
-               DO 20 I = 1, MNOBR - 1
-                  DO 15 J = MMNOBR, NR2, -1
-                     R(J,I) = R(J-MNOBR+I,I)
-   15             CONTINUE
-                  CALL DCOPY( MNOBR-I, DUM, 0, R(I+1,I), 1 )
-                  IWORK(I) = 0
-   20          CONTINUE
-C
-               IWORK(MNOBR) = 0
-C
-C              Workspace: need   5*M*NOBR+1.
-C                         prefer 4*M*NOBR + (M*NOBR+1)*NB.
-C
-               ITAU2  = JWORK
-               JWORK  = ITAU2 + MNOBR
-               SVLMAX = ZERO
-               CALL MB03OD( 'QR', MNOBR, MNOBR, R, LDR, IWORK, TOLL,
-     $                      SVLMAX, DWORK(ITAU2), RANK, SVAL,
-     $                      DWORK(JWORK), LDWORK-JWORK+1, IERR )
-               MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C              Workspace: need   2*M*NOBR + (M+2*L)*NOBR;
-C                         prefer 2*M*NOBR + (M+2*L)*NOBR*NB.
-C
-               CALL DORMQR( 'Left', 'Transpose', MNOBR, LLMNOB, MNOBR,
-     $                      R, LDR, DWORK(ITAU2), R(1,NR2), LDR,
-     $                      DWORK(JWORK), LDWORK-JWORK+1, IERR )
-               MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-               IF ( RANK.LT.MNOBR ) THEN
-C
-C                 The least squares problem is rank-deficient.
-C
-                  IWARN = 4
-               END IF
-C
-C              Determine residuals r_1 and r_2: premultiply by  Q  and
-C              then by  q.
-C              Workspace: need   2*M*NOBR + (M+2*L)*NOBR);
-C                         prefer 2*M*NOBR + (M+2*L)*NOBR*NB.
-C
-               CALL DLASET( 'Full', RANK, LLMNOB, ZERO, ZERO, R(1,NR2),
-     $                      LDR )
-               CALL DORMQR( 'Left', 'NoTranspose', MNOBR, LLMNOB, MNOBR,
-     $                      R, LDR, DWORK(ITAU2), R(1,NR2), LDR,
-     $                      DWORK(JWORK), LDWORK-JWORK+1, IERR )
-               MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-               JWORK  = ITAU2
-C
-C              Restore the transformation  q.
-C
-               DO 30 I = 1, MNOBR - 1
-                  DO 25 J = NR2, MMNOBR
-                     R(J-MNOBR+I,I) = R(J,I)
-   25             CONTINUE
-   30          CONTINUE
-C
-            END IF
-C
-C           Premultiply by the transformation  q  (apply transformations
-C           in backward order).
-C           Workspace: need   M*NOBR + (M+2*L)*NOBR;
-C                      prefer larger.
-C
-            CALL MB04IY( 'Left', 'NoTranspose', MMNOBR, LLMNOB, MNOBR,
-     $                   MNOBR-1, R, LDR, DWORK(ITAU), R(1,NR2), LDR,
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-         ELSE
-C
-C           Save  Y_f  (transposed) in the last block-row of  R.
-C
-            CALL MA02AD( 'Full', LMMNOB, LNOBR, R(1,NR4), LDR, R(NR4,1),
-     $                   LDR )
-            RCOND1 = ONE
-         END IF
-C
-C        Triangularize the matrix  r_1  for determining the oblique
-C        projection  P  in least squares problem in (1).  Exploit the
-C        fact that the third block-row of r_1  has the structure
-C        [ 0  T ],  where  T  is an upper triangular matrix.  Then apply
-C        the corresponding transformations  Q'  to the matrix  r_2.
-C        Workspace: need   2*M*NOBR;
-C                   prefer   M*NOBR + M*NOBR*NB.
-C
-         CALL DGEQRF( MMNOBR, MNOBR, R(1,NR2), LDR, DWORK(ITAU),
-     $                DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-C        Workspace: need   M*NOBR + 2*L*NOBR;
-C                   prefer M*NOBR + 2*L*NOBR*NB.
-C
-         CALL DORMQR( 'Left', 'Transpose', MMNOBR, LLNOBR, MNOBR,
-     $                R(1,NR2), LDR, DWORK(ITAU), R(1,NR3), LDR,
-     $                DWORK(JWORK), LDWORK-JWORK+1, IERR )
-         NRSAVE = NR2
-C
-         ITAU2 = JWORK
-         JWORK = ITAU2 + LNOBR
-         CALL MB04ID( LMNOBR, LNOBR, LNOBR-1, LNOBR, R(NR2,NR3), LDR,
-     $                R(NR2,NR4), LDR, DWORK(ITAU2), DWORK(JWORK),
-     $                LDWORK-JWORK+1, IERR )
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C        Check the condition of the triangular matrix of order  (m+l)*s
-C        just determined, and decide to use pivoting or not.
-C        Workspace: need 4*(M+L)*NOBR.
-C
-         CALL DTRCON( '1-norm', 'Upper', 'NonUnit', LMNOBR, R(1,NR2),
-     $                LDR, RCOND2, DWORK(JWORK), IWORK, IERR )
-C
-         IF( TOL.LE.ZERO )
-     $      TOLL = LMNOBR*LMNOBR*EPS
-         IF ( RCOND2.LE.MAX( TOLL, THRESH ) ) THEN
-            IF ( M.GT.0 ) THEN
-C
-C              Save information about  Q  in  R_11  (in the strict lower
-C              triangle),  R_21  and  R_31  (transposed information).
-C
-               CALL DLACPY( 'Lower', MMNOBR-1, MNOBR, R(2,NR2), LDR,
-     $                      R(2,1), LDR )
-               NRSAVE = 1
-C
-               DO 40 I = NR2, LMNOBR
-                  CALL DCOPY( MNOBR, R(I+1,MNOBR+I), 1, R(MNOBR+I,1),
-     $                        LDR )
-   40          CONTINUE
-C
-            END IF
-C
-            CALL DLASET( 'Lower', LMNOBR-1, LMNOBR-1, ZERO, ZERO,
-     $                   R(2,NR2), LDR )
-C
-C           Use QR factorization with column pivoting.
-C           Workspace: need   5*(M+L)*NOBR+1.
-C                      prefer 4*(M+L)*NOBR + ((M+L)*NOBR+1)*NB.
-C
-            DO 50 I = 1, LMNOBR
-               IWORK(I) = 0
-   50       CONTINUE
-C
-            ITAU3  = JWORK
-            JWORK  = ITAU3 + LMNOBR
-            SVLMAX = ZERO
-            CALL MB03OD( 'QR', LMNOBR, LMNOBR, R(1,NR2), LDR, IWORK,
-     $                   TOLL, SVLMAX, DWORK(ITAU3), RANK1, SVAL,
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C           Workspace: need   2*(M+L)*NOBR + L*NOBR;
-C                      prefer 2*(M+L)*NOBR + L*NOBR*NB.
-C
-            CALL DORMQR( 'Left', 'Transpose', LMNOBR, LNOBR, LMNOBR,
-     $                   R(1,NR2), LDR, DWORK(ITAU3), R(1,NR4), LDR,
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-            IF ( RANK1.LT.LMNOBR ) THEN
-C
-C              The least squares problem is rank-deficient.
-C
-               IWARN = 5
-            END IF
-C
-C           Apply the orthogonal transformations, in backward order, to
-C           [r_2(1:rank(r_1),:)' 0]',  to obtain  P'.
-C           Workspace: need   2*(M+L)*NOBR + L*NOBR;
-C                      prefer 2*(M+L)*NOBR + L*NOBR*NB.
-C
-            CALL DLASET( 'Full', LMNOBR-RANK1, LNOBR, ZERO, ZERO,
-     $                   R(RANK1+1,NR4), LDR )
-            CALL DORMQR( 'Left', 'NoTranspose', LMNOBR, LNOBR, LMNOBR,
-     $                   R(1,NR2), LDR, DWORK(ITAU3), R(1,NR4), LDR,
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-            JWORK = ITAU3
-C
-            IF ( M.GT.0 ) THEN
-C
-C              Restore the saved transpose matrix from  R_31.
-C
-               DO 60 I = NR2, LMNOBR
-                  CALL DCOPY( MNOBR, R(MNOBR+I,1), LDR, R(I+1,MNOBR+I),
-     $                        1 )
-   60          CONTINUE
-C
-            END IF
-C
-         END IF
-C
-C        Workspace: need   M*NOBR + L*NOBR;
-C                   prefer larger.
-C
-         CALL MB04IY( 'Left', 'NoTranspose', LMNOBR, LNOBR, LNOBR,
-     $                LNOBR-1, R(NR2,NR3), LDR, DWORK(ITAU2),
-     $                R(NR2,NR4), LDR, DWORK(JWORK), LDWORK-JWORK+1,
-     $                IERR )
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C        Workspace: need   M*NOBR + L*NOBR;
-C                   prefer M*NOBR + L*NOBR*NB.
-C
-         JWORK = ITAU2
-         CALL DORMQR( 'Left', 'NoTranspose', MMNOBR, LNOBR, MNOBR,
-     $                R(1,NRSAVE), LDR, DWORK(ITAU), R(1,NR4), LDR,
-     $                DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-C        Now, the matrix  P'  is available in  R_14 : R_34.
-C        Triangularize the matrix  P'.
-C        Workspace: need   2*L*NOBR;
-C                   prefer   L*NOBR + L*NOBR*NB.
-C
-         JWORK = ITAU + LNOBR
-         CALL DGEQRF( LMMNOB, LNOBR, R(1,NR4), LDR, DWORK(ITAU),
-     $                DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-C        Copy the triangular factor to its final position,  R_22.
-C
-         CALL DLACPY( 'Upper', LNOBR, LNOBR, R(1,NR4), LDR, R(NR2,NR2),
-     $                LDR )
-C
-C        Restore  Y_f.
-C
-         CALL MA02AD( 'Full', LNOBR, LMMNOB, R(NR4,1), LDR, R(1,NR4),
-     $                LDR )
-      END IF
-C
-C     Find the singular value decomposition of  R_22.
-C     Workspace: need 5*L*NOBR.
-C
-      CALL MB03UD( 'NoVectors', 'Vectors', LNOBR, R(NR2,NR2), LDR,
-     $             DUM, 1, SV, DWORK, LDWORK, IERR )
-      IF ( IERR.NE.0 ) THEN
-         INFO = 2
-         RETURN
-      END IF
-      MAXWRK = MAX( MAXWRK, INT( DWORK(1) ) )
-C
-C     Transpose  R(m*s+1:(m+L)*s,m*s+1:(m+L)*s)  in-situ; its
-C     columns will then be the singular vectors needed subsequently.
-C
-      DO 70 I = NR2+1, LMNOBR
-         CALL DSWAP( LMNOBR-I+1, R(I,I-1), 1, R(I-1,I), LDR )
-   70 CONTINUE
-C
-C     Return optimal workspace in  DWORK(1)  and reciprocal condition
-C     numbers, if  METH = 'N'.
-C
-      DWORK(1) = MAXWRK
-      IF ( N4SID ) THEN
-         DWORK(2) = RCOND1
-         DWORK(3) = RCOND2
-      END IF
-      RETURN
-C
-C *** Last line of IB01ND ***
-      END
--- a/extra/control-devel/src/IB01OD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,214 +0,0 @@
-      SUBROUTINE IB01OD( CTRL, NOBR, L, SV, N, TOL, IWARN, 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 estimate the system order, based on the singular values of the
-C     relevant part of the triangular factor of the concatenated block
-C     Hankel matrices.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     CTRL    CHARACTER*1
-C             Specifies whether or not the user's confirmation of the
-C             system order estimate is desired, as follows:
-C             = 'C':  user's confirmation;
-C             = 'N':  no confirmation.
-C             If  CTRL = 'C',  a reverse communication routine,  IB01OY,
-C             is called, and, after inspecting the singular values and
-C             system order estimate,  n,  the user may accept  n  or set
-C             a new value.
-C             IB01OY  is not called by the routine if CTRL = 'N'.
-C
-C     Input/Output Parameters
-C
-C     NOBR    (input) INTEGER
-C             The number of block rows,  s,  in the processed input and
-C             output block Hankel matrices.  NOBR > 0.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     SV      (input) DOUBLE PRECISION array, dimension ( L*NOBR )
-C             The singular values of the relevant part of the triangular
-C             factor from the QR factorization of the concatenated block
-C             Hankel matrices.
-C
-C     N       (output) INTEGER
-C             The estimated order of the system.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             Absolute tolerance used for determining an estimate of
-C             the system order. If  TOL >= 0,  the estimate is
-C             indicated by the index of the last singular value greater
-C             than or equal to  TOL.  (Singular values less than  TOL
-C             are considered as zero.) When  TOL = 0,  an internally
-C             computed default value,  TOL = NOBR*EPS*SV(1),  is used,
-C             where  SV(1)  is the maximal singular value, and  EPS  is
-C             the relative machine precision (see LAPACK Library routine
-C             DLAMCH). When  TOL < 0,  the estimate is indicated by the
-C             index of the singular value that has the largest
-C             logarithmic gap to its successor.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 3:  all singular values were exactly zero, hence  N = 0.
-C                   (Both input and output were identically zero.)
-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     METHOD
-C
-C     The singular values are compared to the given, or default TOL, and
-C     the estimated order  n  is returned, possibly after user's
-C     confirmation.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 1999.
-C
-C     REVISIONS
-C
-C     August 2000.
-C
-C     KEYWORDS
-C
-C     Identification methods, multivariable systems, singular value
-C     decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO
-      PARAMETER          ( ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   TOL
-      INTEGER            INFO, IWARN, L, N, NOBR
-      CHARACTER          CTRL
-C     .. Array Arguments ..
-      DOUBLE PRECISION   SV(*)
-C     .. Local Scalars ..
-      DOUBLE PRECISION   GAP, RNRM, TOLL
-      INTEGER            I, IERR, LNOBR
-      LOGICAL            CONTRL
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL           IB01OY, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          DBLE, LOG10
-C     ..
-C     .. Executable Statements ..
-C
-C     Check the scalar input parameters.
-C
-      CONTRL = LSAME( CTRL, 'C' )
-      LNOBR  = L*NOBR
-      IWARN  = 0
-      INFO   = 0
-      IF( .NOT.( CONTRL .OR. LSAME( CTRL, 'N' ) ) ) THEN
-         INFO = -1
-      ELSE IF( NOBR.LE.0 ) THEN
-         INFO = -2
-      ELSE IF( L.LE.0 ) THEN
-         INFO = -3
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01OD', -INFO )
-         RETURN
-      END IF
-C
-C     Set  TOL  if necessay.
-C
-      TOLL = TOL
-      IF ( TOLL.EQ.ZERO)
-     $   TOLL = DLAMCH( 'Precision' )*SV(1)*DBLE( NOBR )
-C
-C     Obtain the system order.
-C
-      N = 0
-      IF ( SV(1).NE.ZERO ) THEN
-         N = NOBR
-         IF ( TOLL.GE.ZERO) THEN
-C
-C           Estimate  n  based on the tolerance  TOLL.
-C
-            DO 10 I = 1, NOBR - 1
-               IF ( SV(I+1).LT.TOLL ) THEN
-                  N = I
-                  GO TO 30
-               END IF
-   10       CONTINUE
-         ELSE
-C
-C           Estimate  n  based on the largest logarithmic gap between
-C           two consecutive singular values.
-C
-            GAP = ZERO
-            DO 20 I = 1, NOBR - 1
-               RNRM = SV(I+1)
-               IF ( RNRM.NE.ZERO ) THEN
-                  RNRM = LOG10( SV(I) ) - LOG10( RNRM )
-                  IF ( RNRM.GT.GAP ) THEN
-                     GAP = RNRM
-                     N = I
-                  END IF
-               ELSE
-                  IF ( GAP.EQ.ZERO )
-     $               N = I
-                  GO TO 30
-               END IF
-   20       CONTINUE
-         END IF
-      END IF
-C
-   30 CONTINUE
-      IF ( N.EQ.0 ) THEN
-C
-C        Return with  N = 0  if all singular values are zero.
-C
-         IWARN = 3
-         RETURN
-      END IF
-C
-      IF ( CONTRL ) THEN
-C
-C        Ask confirmation of the system order.
-C
-         CALL IB01OY( LNOBR, NOBR-1, N, SV, IERR )
-      END IF
-      RETURN
-C
-C *** Last line of IB01OD ***
-      END
--- a/extra/control-devel/src/IB01OY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,175 +0,0 @@
-      SUBROUTINE IB01OY( NS, NMAX, N, SV, 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 ask for user's confirmation of the system order found by
-C     SLICOT Library routine IB01OD. This routine may be modified,
-C     but its interface must be preserved.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     NS      (input) INTEGER
-C             The number of singular values.  NS > 0.
-C
-C     NMAX    (input) INTEGER
-C             The maximum value of the system order.  0 <= NMAX <= NS.
-C
-C     N       (input/output) INTEGER
-C             On entry, the estimate of the system order computed by
-C             IB01OD routine.  0 <= N <= NS.
-C             On exit, the user's estimate of the system order, which
-C             could be identical with the input value of  N.
-C             Note that the output value of  N  should be less than
-C             or equal to  NMAX.
-C
-C     SV      (input) DOUBLE PRECISION array, dimension ( NS )
-C             The singular values, in descending order, used for
-C             determining the system order.
-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     CONTRIBUTORS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 1999.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Identification, parameter estimation, singular values, structure
-C     identification.
-C
-C  *********************************************************************
-C
-C     .. Parameters ..
-      INTEGER            INTRMN, OUTRMN
-      PARAMETER          ( INTRMN = 5, OUTRMN = 6 )
-C        INTRMN is the unit number for the (terminal) input device.
-C        OUTRMN is the unit number for the (terminal) output device.
-C     ..
-C     .. Scalar Arguments ..
-      INTEGER            INFO, N, NMAX, NS
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   SV( * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            YES
-      INTEGER            I
-      CHARACTER          ANS
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           XERBLA
-C
-C     .. Executable Statements ..
-C
-C     Check the scalar input parameters.
-C
-      INFO = 0
-      IF( NS.LE.0 ) THEN
-         INFO = -1
-      ELSE IF( NMAX.LT.0 .OR. NMAX.GT.NS ) THEN
-         INFO = -2
-      ELSE IF( N.LT.0 .OR. N.GT.NS ) THEN
-         INFO = -3
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01OY', -INFO )
-         RETURN
-      END IF
-C
-      WRITE( OUTRMN, '(/'' Singular values (in descending order) used'',
-     $                  '' to estimate the system order:'', //
-     $                     (5D15.8) )' ) ( SV(I), I = 1, NS )
-      WRITE( OUTRMN, '(/'' Estimated order of the system,  n = '', I5 )'
-     $     )               N
-      WRITE( OUTRMN, '(/'' Do you want this value of  n  to be used'',
-     $                  '' to determine the system matrices?'' )' )
-C
-   10 CONTINUE
-         WRITE( OUTRMN, '(/''  Type "yes" or "no":  '' )' )
-         READ ( INTRMN,  '( A )' ) ANS
-         YES = LSAME( ANS, 'Y' )
-         IF( YES ) THEN
-            IF( N.LE.NMAX ) THEN
-C
-C              The value of n is adequate and has been confirmed.
-C
-               RETURN
-            ELSE
-C
-C              The estimated value of n is not acceptable.
-C
-               WRITE( OUTRMN, '(/'' n  should be less than or equal'',
-     $                           '' to '', I5 )' ) NMAX
-               WRITE( OUTRMN, '( '' (It may be useful to restart'',
-     $                           '' with a larger tolerance.)'' )' )
-               GO TO 20
-            END IF
-C
-         ELSE IF( LSAME( ANS, 'N' ) ) THEN
-            GO TO 20
-         ELSE
-C
-C           Wrong answer should be re-entered.
-C
-            GO TO 10
-         END IF
-C
-C     Enter the desired value of n.
-C
-   20 CONTINUE
-         WRITE( OUTRMN,'(/'' Enter the desired value of n (n <= '', I5,
-     $                    '');  n = '' )' ) NMAX
-         READ ( INTRMN, * ) N
-         IF ( N.LT.0 ) THEN
-C
-C           The specified value of n is not acceptable.
-C
-            WRITE( OUTRMN, '(/'' n  should be larger than zero.'' )' )
-            GO TO 20
-         ELSE IF ( N.GT.NMAX ) THEN
-C
-C           The specified value of n is not acceptable.
-C
-            WRITE( OUTRMN, '(/'' n  should be less than or equal to '',
-     $                   I5 )' ) NMAX
-            GO TO 20
-         END IF
-C
-      RETURN
-C
-C *** Last line of IB01OY ***
-      END
--- a/extra/control-devel/src/IB01PD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1232 +0,0 @@
-      SUBROUTINE IB01PD( METH, JOB, JOBCV, NOBR, N, M, L, NSMPL, R,
-     $                   LDR, A, LDA, C, LDC, B, LDB, D, LDD, Q, LDQ,
-     $                   RY, LDRY, S, LDS, O, LDO, TOL, IWORK, DWORK,
-     $                   LDWORK, IWARN, 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 estimate the matrices A, C, B, and D of a linear time-invariant
-C     (LTI) state space model, using the singular value decomposition
-C     information provided by other routines. Optionally, the system and
-C     noise covariance matrices, needed for the Kalman gain, are also
-C     determined.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     METH    CHARACTER*1
-C             Specifies the subspace identification method to be used,
-C             as follows:
-C             = 'M':  MOESP  algorithm with past inputs and outputs;
-C             = 'N':  N4SID  algorithm.
-C
-C     JOB     CHARACTER*1
-C             Specifies which matrices should be computed, as follows:
-C             = 'A':  compute all system matrices, A, B, C, and D;
-C             = 'C':  compute the matrices A and C only;
-C             = 'B':  compute the matrix B only;
-C             = 'D':  compute the matrices B and D only.
-C
-C     JOBCV   CHARACTER*1
-C             Specifies whether or not the covariance matrices are to
-C             be computed, as follows:
-C             = 'C':  the covariance matrices should be computed;
-C             = 'N':  the covariance matrices should not be computed.
-C
-C     Input/Output Parameters
-C
-C     NOBR    (input) INTEGER
-C             The number of block rows,  s,  in the input and output
-C             Hankel matrices processed by other routines.  NOBR > 1.
-C
-C     N       (input) INTEGER
-C             The order of the system.  NOBR > N > 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     NSMPL   (input) INTEGER
-C             If JOBCV = 'C', the total number of samples used for
-C             calculating the covariance matrices.
-C             NSMPL >= 2*(M+L)*NOBR.
-C             This parameter is not meaningful if  JOBCV = 'N'.
-C
-C     R       (input/workspace) DOUBLE PRECISION array, dimension
-C             ( LDR,2*(M+L)*NOBR )
-C             On entry, the leading  2*(M+L)*NOBR-by-2*(M+L)*NOBR  part
-C             of this array must contain the relevant data for the MOESP
-C             or N4SID algorithms, as constructed by SLICOT Library
-C             routines IB01AD or IB01ND. Let  R_ij,  i,j = 1:4,  be the
-C             ij submatrix of  R  (denoted  S  in IB01AD and IB01ND),
-C             partitioned by  M*NOBR,  L*NOBR,  M*NOBR,  and  L*NOBR
-C             rows and columns. The submatrix  R_22  contains the matrix
-C             of left singular vectors used. Also needed, for
-C             METH = 'N'  or  JOBCV = 'C',  are the submatrices  R_11,
-C             R_14 : R_44,  and, for  METH = 'M'  and  JOB <> 'C',  the
-C             submatrices  R_31  and  R_12,  containing the processed
-C             matrices  R_1c  and  R_2c,  respectively, as returned by
-C             SLICOT Library routines IB01AD or IB01ND.
-C             Moreover, if  METH = 'N'  and  JOB = 'A' or 'C',  the
-C             block-row  R_41 : R_43  must contain the transpose of the
-C             block-column  R_14 : R_34  as returned by SLICOT Library
-C             routines IB01AD or IB01ND.
-C             The remaining part of  R  is used as workspace.
-C             On exit, part of this array is overwritten. Specifically,
-C             if  METH = 'M',  R_22  and  R_31  are overwritten if
-C                 JOB = 'B' or 'D',  and  R_12,  R_22,  R_14 : R_34,
-C                 and possibly  R_11  are overwritten if  JOBCV = 'C';
-C             if  METH = 'N',  all needed submatrices are overwritten.
-C
-C     LDR     INTEGER
-C             The leading dimension of the array  R.
-C             LDR >= 2*(M+L)*NOBR.
-C
-C     A       (input or output) DOUBLE PRECISION array, dimension
-C             (LDA,N)
-C             On entry, if  METH = 'N'  and  JOB = 'B' or 'D',  the
-C             leading N-by-N part of this array must contain the system
-C             state matrix.
-C             If  METH = 'M'  or  (METH = 'N'  and JOB = 'A' or 'C'),
-C             this array need not be set on input.
-C             On exit, if  JOB = 'A' or 'C'  and  INFO = 0,  the
-C             leading N-by-N part of this array contains the system
-C             state matrix.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.
-C             LDA >= N,  if  JOB = 'A' or 'C',  or  METH = 'N'  and
-C                            JOB = 'B' or 'D';
-C             LDA >= 1,  otherwise.
-C
-C     C       (input or output) DOUBLE PRECISION array, dimension
-C             (LDC,N)
-C             On entry, if  METH = 'N'  and  JOB = 'B' or 'D',  the
-C             leading L-by-N part of this array must contain the system
-C             output matrix.
-C             If  METH = 'M'  or  (METH = 'N'  and JOB = 'A' or 'C'),
-C             this array need not be set on input.
-C             On exit, if  JOB = 'A' or 'C'  and  INFO = 0,  or
-C             INFO = 3  (or  INFO >= 0,  for  METH = 'M'),  the leading
-C             L-by-N part of this array contains the system output
-C             matrix.
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.
-C             LDC >= L,  if  JOB = 'A' or 'C',  or  METH = 'N'  and
-C                            JOB = 'B' or 'D';
-C             LDC >= 1,  otherwise.
-C
-C     B       (output) DOUBLE PRECISION array, dimension (LDB,M)
-C             If  M > 0,  JOB = 'A', 'B', or 'D'  and  INFO = 0,  the
-C             leading N-by-M part of this array contains the system
-C             input matrix. If  M = 0  or  JOB = 'C',  this array is
-C             not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.
-C             LDB >= N,  if M > 0 and JOB = 'A', 'B', or 'D';
-C             LDB >= 1,  if M = 0 or  JOB = 'C'.
-C
-C     D       (output) DOUBLE PRECISION array, dimension (LDD,M)
-C             If  M > 0,  JOB = 'A' or 'D'  and  INFO = 0,  the leading
-C             L-by-M part of this array contains the system input-output
-C             matrix. If  M = 0  or  JOB = 'C' or 'B',  this array is
-C             not referenced.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.
-C             LDD >= L,  if M > 0 and JOB = 'A' or 'D';
-C             LDD >= 1,  if M = 0 or  JOB = 'C' or 'B'.
-C
-C     Q       (output) DOUBLE PRECISION array, dimension (LDQ,N)
-C             If JOBCV = 'C', the leading N-by-N part of this array
-C             contains the positive semidefinite state covariance matrix
-C             to be used as state weighting matrix when computing the
-C             Kalman gain.
-C             This parameter is not referenced if JOBCV = 'N'.
-C
-C     LDQ     INTEGER
-C             The leading dimension of the array Q.
-C             LDQ >= N,  if JOBCV = 'C';
-C             LDQ >= 1,  if JOBCV = 'N'.
-C
-C     RY      (output) DOUBLE PRECISION array, dimension (LDRY,L)
-C             If JOBCV = 'C', the leading L-by-L part of this array
-C             contains the positive (semi)definite output covariance
-C             matrix to be used as output weighting matrix when
-C             computing the Kalman gain.
-C             This parameter is not referenced if JOBCV = 'N'.
-C
-C     LDRY    INTEGER
-C             The leading dimension of the array RY.
-C             LDRY >= L,  if JOBCV = 'C';
-C             LDRY >= 1,  if JOBCV = 'N'.
-C
-C     S       (output) DOUBLE PRECISION array, dimension (LDS,L)
-C             If JOBCV = 'C', the leading N-by-L part of this array
-C             contains the state-output cross-covariance matrix to be
-C             used as cross-weighting matrix when computing the Kalman
-C             gain.
-C             This parameter is not referenced if JOBCV = 'N'.
-C
-C     LDS     INTEGER
-C             The leading dimension of the array S.
-C             LDS >= N,  if JOBCV = 'C';
-C             LDS >= 1,  if JOBCV = 'N'.
-C
-C     O       (output) DOUBLE PRECISION array, dimension ( LDO,N )
-C             If  METH = 'M'  and  JOBCV = 'C',  or  METH = 'N',
-C             the leading  L*NOBR-by-N  part of this array contains
-C             the estimated extended observability matrix, i.e., the
-C             first  N  columns of the relevant singular vectors.
-C             If  METH = 'M'  and  JOBCV = 'N',  this array is not
-C             referenced.
-C
-C     LDO     INTEGER
-C             The leading dimension of the array  O.
-C             LDO >= L*NOBR,  if  JOBCV = 'C'  or  METH = 'N';
-C             LDO >= 1,       otherwise.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used for estimating the rank of
-C             matrices. If the user sets  TOL > 0,  then the given value
-C             of  TOL  is used as a lower bound for the reciprocal
-C             condition number;  an m-by-n matrix whose estimated
-C             condition number is less than  1/TOL  is considered to
-C             be of full rank.  If the user sets  TOL <= 0,  then an
-C             implicitly computed, default tolerance, defined by
-C             TOLDEF = m*n*EPS,  is used instead, where  EPS  is the
-C             relative machine precision (see LAPACK Library routine
-C             DLAMCH).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK = N,                   if METH = 'M' and M = 0
-C                                        or JOB = 'C' and JOBCV = 'N';
-C             LIWORK = M*NOBR+N,            if METH = 'M', JOB = 'C',
-C                                           and JOBCV = 'C';
-C             LIWORK = max(L*NOBR,M*NOBR),  if METH = 'M', JOB <> 'C',
-C                                           and JOBCV = 'N';
-C             LIWORK = max(L*NOBR,M*NOBR+N),  if METH = 'M', JOB <> 'C',
-C                                             and JOBCV = 'C';
-C             LIWORK = max(M*NOBR+N,M*(N+L)), if METH = 'N'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of LDWORK,  and  DWORK(2),  DWORK(3),  DWORK(4),  and
-C             DWORK(5)  contain the reciprocal condition numbers of the
-C             triangular factors of the matrices, defined in the code,
-C             GaL  (GaL = Un(1:(s-1)*L,1:n)),  R_1c  (if  METH = 'M'),
-C             M  (if  JOBCV = 'C'  or  METH = 'N'),  and  Q  or  T  (see
-C             SLICOT Library routines IB01PY or IB01PX),  respectively.
-C             If  METH = 'N',  DWORK(3)  is set to one without any
-C             calculations. Similarly, if  METH = 'M'  and  JOBCV = 'N',
-C             DWORK(4)  is set to one. If  M = 0  or  JOB = 'C',
-C             DWORK(3)  and  DWORK(5)  are set to one.
-C             On exit, if  INFO = -30,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= max( LDW1,LDW2 ), where, if METH = 'M',
-C             LDW1 >= max( 2*(L*NOBR-L)*N+2*N, (L*NOBR-L)*N+N*N+7*N ),
-C                     if JOB = 'C' or JOB = 'A' and M = 0;
-C             LDW1 >= max( 2*(L*NOBR-L)*N+N*N+7*N,
-C                          (L*NOBR-L)*N+N+6*M*NOBR, (L*NOBR-L)*N+N+
-C                          max( L+M*NOBR, L*NOBR +
-C                                         max( 3*L*NOBR+1, M ) ) )
-C                     if M > 0 and JOB = 'A', 'B', or 'D';
-C             LDW2 >= 0,                                 if JOBCV = 'N';
-C             LDW2 >= max( (L*NOBR-L)*N+Aw+2*N+max(5*N,(2*M+L)*NOBR+L),
-C                          4*(M*NOBR+N)+1, M*NOBR+2*N+L ),
-C                                                        if JOBCV = 'C',
-C             where Aw = N+N*N, if M = 0 or JOB = 'C';
-C                   Aw = 0,     otherwise;
-C             and, if METH = 'N',
-C             LDW1 >= max( (L*NOBR-L)*N+2*N+(2*M+L)*NOBR+L,
-C                          2*(L*NOBR-L)*N+N*N+8*N, N+4*(M*NOBR+N)+1,
-C                          M*NOBR+3*N+L );
-C             LDW2 >= 0, if M = 0 or JOB = 'C';
-C             LDW2 >= M*NOBR*(N+L)*(M*(N+L)+1)+
-C                     max( (N+L)**2, 4*M*(N+L)+1 ),
-C                     if M > 0 and JOB = 'A', 'B', or 'D'.
-C             For good performance,  LDWORK  should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 4:  a least squares problem to be solved has a
-C                   rank-deficient coefficient matrix;
-C             = 5:  the computed covariance matrices are too small.
-C                   The problem seems to be a deterministic one.
-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             = 2:  the singular value decomposition (SVD) algorithm did
-C                   not converge;
-C             = 3:  a singular upper triangular matrix was found.
-C
-C     METHOD
-C
-C     In the MOESP approach, the matrices  A  and  C  are first
-C     computed from an estimated extended observability matrix [1],
-C     and then, the matrices  B  and  D  are obtained by solving an
-C     extended linear system in a least squares sense.
-C     In the N4SID approach, besides the estimated extended
-C     observability matrix, the solutions of two least squares problems
-C     are used to build another least squares problem, whose solution
-C     is needed to compute the system matrices  A,  C,  B,  and  D.  The
-C     solutions of the two least squares problems are also optionally
-C     used by both approaches to find the covariance matrices.
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Dewilde, P.
-C         Subspace Model Identification. Part 1: The output-error state-
-C         space model identification class of algorithms.
-C         Int. J. Control, 56, pp. 1187-1210, 1992.
-C
-C     [2] Van Overschee, P., and De Moor, B.
-C         N4SID: Two Subspace Algorithms for the Identification
-C         of Combined Deterministic-Stochastic Systems.
-C         Automatica, Vol.30, No.1, pp. 75-93, 1994.
-C
-C     [3] Van Overschee, P.
-C         Subspace Identification : Theory - Implementation -
-C         Applications.
-C         Ph. D. Thesis, Department of Electrical Engineering,
-C         Katholieke Universiteit Leuven, Belgium, Feb. 1995.
-C
-C     [4] Sima, V.
-C         Subspace-based Algorithms for Multivariable System
-C         Identification.
-C         Studies in Informatics and Control, 5, pp. 335-344, 1996.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is numerically stable.
-C
-C     FURTHER COMMENTS
-C
-C     In some applications, it is useful to compute the system matrices
-C     using two calls to this routine, the first one with  JOB = 'C',
-C     and the second one with  JOB = 'B' or 'D'.  This is slightly less
-C     efficient than using a single call with  JOB = 'A',  because some
-C     calculations are repeated. If  METH = 'N',  all the calculations
-C     at the first call are performed again at the second call;
-C     moreover, it is required to save the needed submatrices of  R
-C     before the first call and restore them before the second call.
-C     If the covariance matrices are desired,  JOBCV  should be set
-C     to  'C'  at the second call. If  B  and  D  are both needed, they
-C     should be computed at once.
-C     It is possible to compute the matrices A and C using the MOESP
-C     algorithm (METH = 'M'), and the matrices B and D using the N4SID
-C     algorithm (METH = 'N'). This combination could be slightly more
-C     efficient than N4SID algorithm alone and it could be more accurate
-C     than MOESP algorithm. No saving/restoring is needed in such a
-C     combination, provided  JOBCV  is set to  'N'  at the first call.
-C     Recommended usage:  either one call with  JOB = 'A',  or
-C        first  call with  METH = 'M',  JOB = 'C',  JOBCV = 'N',
-C        second call with  METH = 'M',  JOB = 'D',  JOBCV = 'C',  or
-C        first  call with  METH = 'M',  JOB = 'C',  JOBCV = 'N',
-C        second call with  METH = 'N',  JOB = 'D',  JOBCV = 'C'.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Dec. 1999.
-C
-C     REVISIONS
-C
-C     March 2000, Feb. 2001, Sep. 2001, March 2005.
-C
-C     KEYWORDS
-C
-C     Identification methods; least squares solutions; multivariable
-C     systems; QR decomposition; singular value decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, THREE
-      PARAMETER          ( ZERO  = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
-     $                     THREE = 3.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   TOL
-      INTEGER            INFO, IWARN, L, LDA, LDB, LDC, LDD, LDO, LDQ,
-     $                   LDR, LDRY, LDS, LDWORK, M, N, NOBR, NSMPL
-      CHARACTER          JOB, JOBCV, METH
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA, *), B(LDB, *), C(LDC, *), D(LDD, *),
-     $                   DWORK(*),  O(LDO, *), Q(LDQ, *), R(LDR, *),
-     $                   RY(LDRY, *), S(LDS, *)
-      INTEGER            IWORK( * )
-C     .. Local Scalars ..
-      DOUBLE PRECISION   EPS, RCOND1, RCOND2, RCOND3, RCOND4, RNRM,
-     $                   SVLMAX, THRESH, TOLL, TOLL1
-      INTEGER            I, IAW, ID, IERR, IGAL, IHOUS, ISV, ITAU,
-     $                   ITAU1, ITAU2, IU, IUN2, IWARNL, IX, JWORK,
-     $                   LDUN2, LDUNN, LDW, LMMNOB, LMMNOL, LMNOBR,
-     $                   LNOBR, LNOBRN, MAXWRK, MINWRK, MNOBR, MNOBRN,
-     $                   N2, NCOL, NN, NPL, NR, NR2, NR3, NR4, NR4MN,
-     $                   NR4PL, NROW, RANK, RANK11, RANKM
-      CHARACTER          FACT, JOBP, JOBPY
-      LOGICAL            FULLR, MOESP, N4SID, SHIFT, WITHAL, WITHB,
-     $                   WITHC, WITHCO, WITHD
-C     .. Local Array ..
-      DOUBLE PRECISION   SVAL(3)
-C     .. External Functions ..
-      LOGICAL            LSAME
-      INTEGER            ILAENV
-      DOUBLE PRECISION   DLAMCH, DLANGE
-      EXTERNAL           DLAMCH, DLANGE, ILAENV, LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DCOPY, DGEMM, DGEQRF, DLACPY, DLASET, DORMQR,
-     $                   DSYRK, DTRCON, DTRSM, DTRTRS, IB01PX, IB01PY,
-     $                   MA02AD, MA02ED, MB02QY, MB02UD, MB03OD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          DBLE, MAX
-C     .. Executable Statements ..
-C
-C     Decode the scalar input parameters.
-C
-      MOESP  = LSAME( METH,  'M' )
-      N4SID  = LSAME( METH,  'N' )
-      WITHAL = LSAME( JOB,   'A' )
-      WITHC  = LSAME( JOB,   'C' ) .OR. WITHAL
-      WITHD  = LSAME( JOB,   'D' ) .OR. WITHAL
-      WITHB  = LSAME( JOB,   'B' ) .OR. WITHD
-      WITHCO = LSAME( JOBCV, 'C' )
-      MNOBR  = M*NOBR
-      LNOBR  = L*NOBR
-      LMNOBR = LNOBR + MNOBR
-      LMMNOB = LNOBR + 2*MNOBR
-      MNOBRN = MNOBR + N
-      LNOBRN = LNOBR - N
-      LDUN2  = LNOBR - L
-      LDUNN  = LDUN2*N
-      LMMNOL = LMMNOB + L
-      NR     = LMNOBR + LMNOBR
-      NPL    = N + L
-      N2     = N + N
-      NN     = N*N
-      MINWRK = 1
-      IWARN  = 0
-      INFO   = 0
-C
-C     Check the scalar input parameters.
-C
-      IF( .NOT.( MOESP .OR. N4SID ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( WITHB .OR. WITHC ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.( WITHCO .OR. LSAME( JOBCV, 'N' ) ) ) THEN
-         INFO = -3
-      ELSE IF( NOBR.LE.1 ) THEN
-         INFO = -4
-      ELSE IF( N.LE.0 .OR. N.GE.NOBR ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( L.LE.0 ) THEN
-         INFO = -7
-      ELSE IF( WITHCO .AND. NSMPL.LT.NR ) THEN
-         INFO = -8
-      ELSE IF( LDR.LT.NR ) THEN
-         INFO = -10
-      ELSE IF( LDA.LT.1 .OR. ( ( WITHC .OR. ( WITHB .AND. N4SID ) )
-     $   .AND. LDA.LT.N ) ) THEN
-         INFO = -12
-      ELSE IF( LDC.LT.1 .OR. ( ( WITHC .OR. ( WITHB .AND. N4SID ) )
-     $   .AND. LDC.LT.L ) ) THEN
-         INFO = -14
-      ELSE IF( LDB.LT.1  .OR. ( WITHB  .AND. LDB.LT.N .AND. M.GT.0 ) )
-     $      THEN
-         INFO = -16
-      ELSE IF( LDD.LT.1  .OR. ( WITHD  .AND. LDD.LT.L .AND. M.GT.0 ) )
-     $      THEN
-         INFO = -18
-      ELSE IF( LDQ.LT.1  .OR. ( WITHCO .AND. LDQ.LT.N ) )  THEN
-         INFO = -20
-      ELSE IF( LDRY.LT.1 .OR. ( WITHCO .AND. LDRY.LT.L ) ) THEN
-         INFO = -22
-      ELSE IF( LDS.LT.1  .OR. ( WITHCO .AND. LDS.LT.N ) )  THEN
-         INFO = -24
-      ELSE IF( LDO.LT.1  .OR. ( ( WITHCO .OR. N4SID ) .AND.
-     $         LDO.LT.LNOBR ) )  THEN
-         INFO = -26
-      ELSE
-C
-C        Compute workspace.
-C        (Note: Comments in the code beginning "Workspace:" describe the
-C         minimal amount of workspace needed at that point in the code,
-C         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
-         IAW    = 0
-         MINWRK = LDUNN + 4*N
-         MAXWRK = LDUNN + N + N*ILAENV( 1, 'DGEQRF', ' ', LDUN2, N, -1,
-     $                                  -1 )
-         IF( MOESP ) THEN
-            ID = 0
-            IF( WITHC ) THEN
-               MINWRK = MAX( MINWRK, 2*LDUNN + N2, LDUNN + NN + 7*N )
-               MAXWRK = MAX( MAXWRK, 2*LDUNN + N + N*ILAENV( 1,
-     $                               'DORMQR', 'LT', LDUN2, N, N, -1 ) )
-            END IF
-         ELSE
-            ID = N
-         END IF
-C
-         IF( ( M.GT.0 .AND. WITHB ) .OR. N4SID ) THEN
-            MINWRK = MAX( MINWRK, 2*LDUNN + NN + ID + 7*N )
-            IF ( MOESP )
-     $         MINWRK = MAX( MINWRK, LDUNN + N + 6*MNOBR, LDUNN + N +
-     $                       MAX( L + MNOBR, LNOBR +
-     $                                       MAX( 3*LNOBR + 1, M ) ) )
-         ELSE
-            IF( MOESP )
-     $         IAW = N + NN
-         END IF
-C
-         IF( N4SID .OR. WITHCO ) THEN
-            MINWRK = MAX( MINWRK, LDUNN + IAW + N2 + MAX( 5*N, LMMNOL ),
-     $                    ID + 4*MNOBRN+1, ID + MNOBRN + NPL )
-            MAXWRK = MAX( MAXWRK, LDUNN + IAW + N2 +
-     $                    MAX( N*ILAENV( 1, 'DGEQRF', ' ', LNOBR, N, -1,
-     $                                   -1 ), LMMNOB*
-     $                           ILAENV( 1, 'DORMQR', 'LT', LNOBR,
-     $                                   LMMNOB, N, -1 ), LMMNOL*
-     $                           ILAENV( 1, 'DORMQR', 'LT', LDUN2,
-     $                                   LMMNOL, N, -1 ) ),
-     $                    ID + N + N*ILAENV( 1, 'DGEQRF', ' ', LMNOBR,
-     $                                       N, -1, -1 ),
-     $                    ID + N + NPL*ILAENV( 1, 'DORMQR', 'LT',
-     $                                         LMNOBR, NPL, N, -1 ) )
-            IF( N4SID .AND. ( M.GT.0 .AND. WITHB ) )
-     $         MINWRK = MAX( MINWRK, MNOBR*NPL*( M*NPL + 1 ) +
-     $                       MAX( NPL**2, 4*M*NPL + 1 ) )
-         END IF
-         MAXWRK = MAX( MINWRK, MAXWRK )
-C
-         IF ( LDWORK.LT.MINWRK ) THEN
-            INFO = -30
-            DWORK( 1 ) = MINWRK
-         END IF
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01PD', -INFO )
-         RETURN
-      END IF
-C
-      NR2 = MNOBR  + 1
-      NR3 = LMNOBR + 1
-      NR4 = LMMNOB + 1
-C
-C     Set the precision parameters. A threshold value  EPS**(2/3)  is
-C     used for deciding to use pivoting or not, where  EPS  is the
-C     relative machine precision (see LAPACK Library routine DLAMCH).
-C
-      EPS    = DLAMCH( 'Precision' )
-      THRESH = EPS**( TWO/THREE )
-      SVLMAX = ZERO
-      RCOND4 = ONE
-C
-C     Let  Un  be the matrix of left singular vectors (stored in  R_22).
-C     Copy  un1 = GaL = Un(1:(s-1)*L,1:n)  in the workspace.
-C
-      IGAL = 1
-      CALL DLACPY( 'Full', LDUN2, N, R(NR2,NR2), LDR, DWORK(IGAL),
-     $             LDUN2 )
-C
-C     Factor un1 = Q1*[r1'  0]' (' means transposition).
-C     Workspace: need   L*(NOBR-1)*N+2*N,
-C                prefer L*(NOBR-1)*N+N+N*NB.
-C
-      ITAU1 = IGAL  + LDUNN
-      JWORK = ITAU1 + N
-      LDW   = JWORK
-      CALL DGEQRF( LDUN2, N, DWORK(IGAL), LDUN2, DWORK(ITAU1),
-     $             DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-C     Compute the reciprocal of the condition number of r1.
-C     Workspace: need L*(NOBR-1)*N+4*N.
-C
-      CALL DTRCON( '1-norm', 'Upper', 'NonUnit', N, DWORK(IGAL), LDUN2,
-     $             RCOND1, DWORK(JWORK), IWORK, INFO )
-C
-      TOLL1 = TOL
-      IF( TOLL1.LE.ZERO )
-     $   TOLL1 = NN*EPS
-C
-      IF ( ( M.GT.0 .AND. WITHB ) .OR. N4SID ) THEN
-         JOBP = 'P'
-         IF ( WITHAL ) THEN
-            JOBPY = 'D'
-         ELSE
-            JOBPY = JOB
-         END IF
-      ELSE
-         JOBP = 'N'
-      END IF
-C
-      IF ( MOESP ) THEN
-         NCOL = 0
-         IUN2 = JWORK
-         IF ( WITHC ) THEN
-C
-C           Set  C = Un(1:L,1:n)  and then compute the system matrix A.
-C
-C           Set  un2 = Un(L+1:L*s,1:n)  in  DWORK(IUN2).
-C           Workspace: need   2*L*(NOBR-1)*N+N.
-C
-            CALL DLACPY( 'Full', L, N, R(NR2,NR2), LDR, C, LDC )
-            CALL DLACPY( 'Full', LDUN2, N, R(NR2+L,NR2), LDR,
-     $                   DWORK(IUN2), LDUN2 )
-C
-C           Note that un1 has already been factored as
-C           un1 = Q1*[r1'  0]'  and usually (generically, assuming
-C           observability) has full column rank.
-C           Update  un2 <-- Q1'*un2  in  DWORK(IUN2)  and save its
-C           first  n  rows in  A.
-C           Workspace: need   2*L*(NOBR-1)*N+2*N;
-C                      prefer 2*L*(NOBR-1)*N+N+N*NB.
-C
-            JWORK = IUN2 + LDUNN
-            CALL DORMQR( 'Left', 'Transpose', LDUN2, N, N, DWORK(IGAL),
-     $                   LDUN2, DWORK(ITAU1), DWORK(IUN2), LDUN2,
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            CALL DLACPY( 'Full', N, N, DWORK(IUN2), LDUN2, A, LDA )
-            NCOL  = N
-            JWORK = IUN2
-         END IF
-C
-         IF ( RCOND1.GT.MAX( TOLL1, THRESH ) ) THEN
-C
-C           The triangular factor r1 is considered to be of full rank.
-C           Solve for  A  (if requested),  r1*A = un2(1:n,:)  in  A.
-C
-            IF ( WITHC ) THEN
-               CALL DTRTRS( 'Upper', 'NoTranspose', 'NonUnit', N, N,
-     $                      DWORK(IGAL), LDUN2, A, LDA, IERR )
-               IF ( IERR.GT.0 ) THEN
-                  INFO = 3
-                  RETURN
-               END IF
-            END IF
-            RANK = N
-         ELSE
-C
-C           Rank-deficient triangular factor r1.  Use SVD of r1,
-C           r1 = U*S*V',  also for computing  A  (if requested) from
-C           r1*A = un2(1:n,:).  Matrix  U  is computed in  DWORK(IU),
-C           and  V' overwrites  r1.  If  B  is requested, the
-C           pseudoinverse of  r1  and then of  GaL  are also computed
-C           in  R(NR3,NR2).
-C           Workspace: need   c*L*(NOBR-1)*N+N*N+7*N,
-C                             where  c = 1  if  B and D  are not needed,
-C                                    c = 2  if  B and D  are needed;
-C                      prefer larger.
-C
-            IU    = IUN2
-            ISV   = IU  + NN
-            JWORK = ISV + N
-            IF ( M.GT.0 .AND. WITHB ) THEN
-C
-C              Save the elementary reflectors used for computing r1,
-C              if  B, D  are needed.
-C              Workspace: need   2*L*(NOBR-1)*N+2*N+N*N.
-C
-               IHOUS = JWORK
-               JWORK = IHOUS + LDUNN
-               CALL DLACPY( 'Lower', LDUN2, N, DWORK(IGAL), LDUN2,
-     $                      DWORK(IHOUS), LDUN2 )
-            ELSE
-               IHOUS = IGAL
-            END IF
-C
-            CALL MB02UD( 'Not factored', 'Left', 'NoTranspose', JOBP, N,
-     $                   NCOL, ONE, TOLL1, RANK, DWORK(IGAL), LDUN2,
-     $                   DWORK(IU), N, DWORK(ISV), A, LDA, R(NR3,NR2),
-     $                   LDR, DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            IF ( IERR.NE.0 ) THEN
-               INFO = 2
-               RETURN
-            END IF
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-            IF ( RANK.EQ.0 ) THEN
-               JOBP = 'N'
-            ELSE IF ( M.GT.0 .AND. WITHB ) THEN
-C
-C              Compute  pinv(GaL)  in  R(NR3,NR2)  if  B, D  are needed.
-C              Workspace: need   2*L*(NOBR-1)*N+N*N+3*N;
-C                         prefer 2*L*(NOBR-1)*N+N*N+2*N+N*NB.
-C
-               CALL DLASET( 'Full', N, LDUN2-N, ZERO, ZERO,
-     $                      R(NR3,NR2+N), LDR )
-               CALL DORMQR( 'Right', 'Transpose', N, LDUN2, N,
-     $                      DWORK(IHOUS), LDUN2, DWORK(ITAU1),
-     $                      R(NR3,NR2), LDR, DWORK(JWORK),
-     $                      LDWORK-JWORK+1, IERR )
-               MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-               IF ( WITHCO ) THEN
-C
-C                 Save  pinv(GaL)  in  DWORK(IGAL).
-C
-                  CALL DLACPY( 'Full', N, LDUN2, R(NR3,NR2), LDR,
-     $                         DWORK(IGAL), N )
-               END IF
-               JWORK = IUN2
-            END IF
-            LDW = JWORK
-         END IF
-C
-         IF ( M.GT.0 .AND. WITHB ) THEN
-C
-C           Computation of  B  and  D.
-C
-C           Compute the reciprocal of the condition number of R_1c.
-C           Workspace: need L*(NOBR-1)*N+N+3*M*NOBR.
-C
-            CALL DTRCON( '1-norm', 'Upper', 'NonUnit', MNOBR, R(NR3,1),
-     $                   LDR, RCOND2, DWORK(JWORK), IWORK, IERR )
-C
-            TOLL = TOL
-            IF( TOLL.LE.ZERO )
-     $         TOLL = MNOBR*MNOBR*EPS
-C
-C           Compute the right hand side and solve for  K  (in  R_23),
-C              K*R_1c' = u2'*R_2c',
-C           where  u2 = Un(:,n+1:L*s),  and  K  is  (Ls-n) x ms.
-C
-            CALL DGEMM( 'Transpose', 'Transpose', LNOBRN, MNOBR, LNOBR,
-     $                   ONE, R(NR2,NR2+N), LDR, R(1,NR2), LDR, ZERO,
-     $                   R(NR2,NR3), LDR )
-C
-            IF ( RCOND2.GT.MAX( TOLL, THRESH ) ) THEN
-C
-C              The triangular factor R_1c is considered to be of full
-C              rank. Solve for  K,  K*R_1c' = u2'*R_2c'.
-C
-               CALL DTRSM( 'Right', 'Upper', 'Transpose', 'Non-unit',
-     $                     LNOBRN, MNOBR, ONE, R(NR3,1), LDR,
-     $                     R(NR2,NR3), LDR )
-            ELSE
-C
-C              Rank-deficient triangular factor  R_1c.  Use SVD of  R_1c
-C              for computing  K  from  K*R_1c' = u2'*R_2c',  where
-C              R_1c = U1*S1*V1'.  Matrix  U1  is computed in  R_33,
-C              and  V1'  overwrites  R_1c.
-C              Workspace: need   L*(NOBR-1)*N+N+6*M*NOBR;
-C                         prefer larger.
-C
-               ISV   = LDW
-               JWORK = ISV + MNOBR
-               CALL MB02UD( 'Not factored', 'Right', 'Transpose',
-     $                      'No pinv', LNOBRN, MNOBR, ONE, TOLL, RANK11,
-     $                      R(NR3,1), LDR, R(NR3,NR3), LDR, DWORK(ISV),
-     $                      R(NR2,NR3), LDR, DWORK(JWORK), 1,
-     $                      DWORK(JWORK), LDWORK-JWORK+1, IERR )
-               IF ( IERR.NE.0 ) THEN
-                  INFO = 2
-                  RETURN
-               END IF
-               MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-               JWORK  = LDW
-            END IF
-C
-C           Compute the triangular factor of the structured matrix  Q
-C           and apply the transformations to the matrix  Kexpand,  where
-C           Q  and  Kexpand  are defined in SLICOT Library routine
-C           IB01PY.  Compute also the matrices  B,  D.
-C           Workspace: need   L*(NOBR-1)*N+N+max(L+M*NOBR,L*NOBR+
-C                                                max(3*L*NOBR+1,M));
-C                      prefer larger.
-C
-            IF ( WITHCO )
-     $         CALL DLACPY( 'Full', LNOBR, N, R(NR2,NR2), LDR, O, LDO )
-            CALL IB01PY( METH, JOBPY, NOBR, N, M, L, RANK, R(NR2,NR2),
-     $                   LDR, DWORK(IGAL), LDUN2, DWORK(ITAU1),
-     $                   R(NR3,NR2), LDR, R(NR2,NR3), LDR, R(NR4,NR2),
-     $                   LDR, R(NR4,NR3), LDR, B, LDB, D, LDD, TOL,
-     $                   IWORK, DWORK(JWORK), LDWORK-JWORK+1, IWARN,
-     $                   INFO )
-            IF ( INFO.NE.0 )
-     $         RETURN
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-            RCOND4 = DWORK(JWORK+1)
-            IF ( WITHCO )
-     $         CALL DLACPY( 'Full', LNOBR, N, O, LDO, R(NR2,1), LDR )
-C
-         ELSE
-            RCOND2 = ONE
-         END IF
-C
-         IF ( .NOT.WITHCO ) THEN
-            RCOND3 = ONE
-            GO TO 30
-         END IF
-      ELSE
-C
-C        For N4SID, set  RCOND2  to one.
-C
-         RCOND2 = ONE
-      END IF
-C
-C     If needed, save the first  n  columns, representing  Gam,  of the
-C     matrix of left singular vectors,  Un,  in  R_21  and in  O.
-C
-      IF ( N4SID .OR. ( WITHC .AND. .NOT.WITHAL ) ) THEN
-         IF ( M.GT.0 )
-     $      CALL DLACPY( 'Full', LNOBR, N, R(NR2,NR2), LDR, R(NR2,1),
-     $                   LDR )
-         CALL DLACPY( 'Full', LNOBR, N, R(NR2,NR2), LDR, O, LDO )
-      END IF
-C
-C     Computations for covariance matrices, and system matrices (N4SID).
-C     Solve the least squares problems  Gam*Y = R4(1:L*s,1:(2*m+L)*s),
-C                                       GaL*X = R4(L+1:L*s,:),  where
-C     GaL = Gam(1:L*(s-1),:),  Gam  has full column rank, and
-C     R4 = [ R_14' R_24' R_34' R_44L' ],  R_44L = R_44(1:L,:), as
-C     returned by SLICOT Library routine  IB01ND.
-C     First, find the  QR  factorization of  Gam,  Gam = Q*R.
-C     Workspace: need   L*(NOBR-1)*N+Aw+3*N;
-C                prefer L*(NOBR-1)*N+Aw+2*N+N*NB, where
-C                Aw = N+N*N,  if  (M = 0  or  JOB = 'C'),  rank(r1) < N,
-C                             and  METH = 'M';
-C                Aw = 0,      otherwise.
-C
-      ITAU2 = LDW
-      JWORK = ITAU2 + N
-      CALL DGEQRF( LNOBR, N, R(NR2,1), LDR, DWORK(ITAU2),
-     $             DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-C     For METH = 'M' or when JOB = 'B' or 'D', transpose
-C     [ R_14' R_24' R_34' ]'  in the last block-row of  R, obtaining  Z,
-C     and for METH = 'N' and JOB = 'A' or 'C', use the matrix  Z
-C     already available in the last block-row of  R,  and then apply
-C     the transformations, Z <-- Q'*Z.
-C     Workspace: need   L*(NOBR-1)*N+Aw+2*N+(2*M+L)*NOBR;
-C                prefer L*(NOBR-1)*N+Aw+2*N+(2*M+L)*NOBR*NB.
-C
-      IF ( MOESP .OR. ( WITHB .AND. .NOT. WITHAL ) )
-     $   CALL MA02AD( 'Full', LMMNOB, LNOBR, R(1,NR4), LDR, R(NR4,1),
-     $                LDR )
-      CALL DORMQR( 'Left', 'Transpose', LNOBR, LMMNOB, N, R(NR2,1), LDR,
-     $             DWORK(ITAU2), R(NR4,1), LDR, DWORK(JWORK),
-     $             LDWORK-JWORK+1, IERR )
-C
-C     Solve for  Y,  RY = Z  in  Z  and save the transpose of the
-C     solution  Y  in the second block-column of  R.
-C
-      CALL DTRTRS( 'Upper', 'NoTranspose', 'NonUnit', N, LMMNOB,
-     $             R(NR2,1), LDR, R(NR4,1), LDR, IERR )
-      IF ( IERR.GT.0 ) THEN
-         INFO = 3
-         RETURN
-      END IF
-      CALL MA02AD( 'Full', N, LMMNOB, R(NR4,1), LDR, R(1,NR2), LDR )
-      NR4MN = NR4 - N
-      NR4PL = NR4 + L
-      NROW  = LMMNOL
-C
-C     SHIFT is .TRUE. if some columns of  R_14 : R_44L  should be
-C     shifted to the right, to avoid overwriting useful information.
-C
-      SHIFT = M.EQ.0 .AND. LNOBR.LT.N2
-C
-      IF ( RCOND1.GT.MAX( TOLL1, THRESH ) ) THEN
-C
-C        The triangular factor  r1  of  GaL  (GaL = Q1*r1)  is
-C        considered to be of full rank.
-C
-C        Transpose  [ R_14' R_24' R_34' R_44L' ]'(:,L+1:L*s)  in the
-C        last block-row of  R  (beginning with the  (L+1)-th  row),
-C        obtaining  Z1,  and then apply the transformations,
-C        Z1 <-- Q1'*Z1.
-C        Workspace: need   L*(NOBR-1)*N+Aw+2*N+ (2*M+L)*NOBR + L;
-C                   prefer L*(NOBR-1)*N+Aw+2*N+((2*M+L)*NOBR + L)*NB.
-C
-         CALL MA02AD( 'Full', LMMNOL, LDUN2, R(1,NR4PL), LDR,
-     $                R(NR4PL,1), LDR )
-         CALL DORMQR( 'Left', 'Transpose', LDUN2, LMMNOL, N,
-     $                DWORK(IGAL), LDUN2, DWORK(ITAU1), R(NR4PL,1), LDR,
-     $                DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-C        Solve for  X,  r1*X = Z1  in  Z1,  and copy the transpose of  X
-C        into the last part of the third block-column of  R.
-C
-         CALL DTRTRS( 'Upper', 'NoTranspose', 'NonUnit', N, LMMNOL,
-     $                DWORK(IGAL), LDUN2, R(NR4PL,1), LDR, IERR )
-         IF ( IERR.GT.0 ) THEN
-            INFO = 3
-            RETURN
-         END IF
-C
-         IF ( SHIFT ) THEN
-            NR4MN = NR4
-C
-            DO 10 I = L - 1, 0, -1
-               CALL DCOPY( LMMNOL, R(1,NR4+I), 1, R(1,NR4+N+I), 1 )
-   10       CONTINUE
-C
-         END IF
-         CALL MA02AD( 'Full', N, LMMNOL, R(NR4PL,1), LDR, R(1,NR4MN),
-     $                LDR )
-         NROW = 0
-      END IF
-C
-      IF ( N4SID .OR. NROW.GT.0 ) THEN
-C
-C        METH = 'N'  or rank-deficient triangular factor r1.
-C        For  METH = 'N',  use SVD of  r1,  r1 = U*S*V', for computing
-C        X'  from  X'*GaL' = Z1',  if  rank(r1) < N.  Matrix  U  is
-C        computed in  DWORK(IU)  and  V'  overwrites  r1.  Then, the
-C        pseudoinverse of  GaL  is determined in  R(NR4+L,NR2).
-C        For METH = 'M', the pseudoinverse of  GaL  is already available
-C        if  M > 0  and  B  is requested;  otherwise, the SVD of  r1  is
-C        available in  DWORK(IU),  DWORK(ISV),  and  DWORK(IGAL).
-C        Workspace for N4SID: need   2*L*(NOBR-1)*N+N*N+8*N;
-C                             prefer larger.
-C
-         IF ( MOESP ) THEN
-            FACT = 'F'
-            IF ( M.GT.0 .AND. WITHB )
-     $         CALL DLACPY( 'Full', N, LDUN2, DWORK(IGAL), N,
-     $                      R(NR4PL,NR2), LDR )
-         ELSE
-C
-C           Save the elementary reflectors used for computing r1.
-C
-            IHOUS = JWORK
-            CALL DLACPY( 'Lower', LDUN2, N, DWORK(IGAL), LDUN2,
-     $                   DWORK(IHOUS), LDUN2 )
-            FACT  = 'N'
-            IU    = IHOUS + LDUNN
-            ISV   = IU  + NN
-            JWORK = ISV + N
-         END IF
-C
-         CALL MB02UD( FACT, 'Right', 'Transpose', JOBP, NROW, N, ONE,
-     $                TOLL1, RANK, DWORK(IGAL), LDUN2, DWORK(IU), N,
-     $                DWORK(ISV), R(1,NR4PL), LDR, R(NR4PL,NR2), LDR,
-     $                DWORK(JWORK), LDWORK-JWORK+1, IERR )
-         IF ( NROW.GT.0 ) THEN
-            IF ( SHIFT ) THEN
-               NR4MN = NR4
-               CALL DLACPY( 'Full', LMMNOL, L, R(1,NR4), LDR,
-     $                      R(1,NR4-L), LDR )
-               CALL DLACPY( 'Full', LMMNOL, N, R(1,NR4PL), LDR,
-     $                      R(1,NR4MN), LDR )
-               CALL DLACPY( 'Full', LMMNOL, L, R(1,NR4-L), LDR,
-     $                      R(1,NR4+N), LDR )
-            ELSE
-               CALL DLACPY( 'Full', LMMNOL, N, R(1,NR4PL), LDR,
-     $                      R(1,NR4MN), LDR )
-            END IF
-         END IF
-C
-         IF ( N4SID ) THEN
-            IF ( IERR.NE.0 ) THEN
-               INFO = 2
-               RETURN
-            END IF
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C           Compute  pinv(GaL)  in  R(NR4+L,NR2).
-C           Workspace: need   2*L*(NOBR-1)*N+3*N;
-C                      prefer 2*L*(NOBR-1)*N+2*N+N*NB.
-C
-            JWORK = IU
-            CALL DLASET( 'Full', N, LDUN2-N, ZERO, ZERO, R(NR4PL,NR2+N),
-     $                   LDR )
-            CALL DORMQR( 'Right', 'Transpose', N, LDUN2, N,
-     $                   DWORK(IHOUS), LDUN2, DWORK(ITAU1),
-     $                   R(NR4PL,NR2), LDR, DWORK(JWORK),
-     $                   LDWORK-JWORK+1, IERR )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-         END IF
-      END IF
-C
-C     For METH = 'N', find part of the solution (corresponding to A
-C     and C) and, optionally, for both  METH = 'M',  or  METH = 'N',
-C     find the residual of the least squares problem that gives the
-C     covariances,  M*V = N,  where
-C         (     R_11 )
-C     M = (  Y'      ),  N = (  X'   R4'(:,1:L) ),  V = V(n+m*s, n+L),
-C         (  0   0   )
-C     with  M((2*m+L)*s+L, n+m*s),  N((2*m+L)*s+L, n+L),  R4'  being
-C     stored in the last block-column of  R.  The last  L  rows of  M
-C     are not explicitly considered. Note that, for efficiency, the
-C     last  m*s  columns of  M  are in the first positions of arrray  R.
-C     This permutation does not affect the residual, only the
-C     solution.  (The solution is not needed for METH = 'M'.)
-C     Note that R_11 corresponds to the future outputs for both
-C     METH = 'M', or METH = 'N' approaches.  (For  METH = 'N',  the
-C     first two block-columns have been interchanged.)
-C     For  METH = 'N',  A and C are obtained as follows:
-C     [ A'  C' ] = V(m*s+1:m*s+n,:).
-C
-C     First, find the  QR  factorization of  Y'(m*s+1:(2*m+L)*s,:)
-C     and apply the transformations to the corresponding part of N.
-C     Compress the workspace for N4SID by moving the scalar reflectors
-C     corresponding to  Q.
-C     Workspace: need   d*N+2*N;
-C                prefer d*N+N+N*NB;
-C     where  d = 0,  for  MOESP,  and  d = 1,  for  N4SID.
-C
-      IF ( MOESP ) THEN
-         ITAU = 1
-      ELSE
-         CALL DCOPY( N, DWORK(ITAU2), 1, DWORK, 1 )
-         ITAU = N + 1
-      END IF
-C
-      JWORK = ITAU + N
-      CALL DGEQRF( LMNOBR, N, R(NR2,NR2), LDR, DWORK(ITAU),
-     $             DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-C     Workspace: need   d*N+N+(N+L);
-C                prefer d*N+N+(N+L)*NB.
-C
-      CALL DORMQR( 'Left', 'Transpose', LMNOBR, NPL, N, R(NR2,NR2), LDR,
-     $             DWORK(ITAU), R(NR2,NR4MN), LDR, DWORK(JWORK),
-     $             LDWORK-JWORK+1, IERR )
-C
-      CALL DLASET( 'Lower', L-1, L-1, ZERO, ZERO, R(NR4+1,NR4), LDR )
-C
-C     Now, matrix  M  with permuted block-columns has been
-C     triangularized.
-C     Compute the reciprocal of the condition number of its
-C     triangular factor in  R(1:m*s+n,1:m*s+n).
-C     Workspace: need d*N+3*(M*NOBR+N).
-C
-      JWORK = ITAU
-      CALL DTRCON( '1-norm', 'Upper', 'NonUnit', MNOBRN, R, LDR, RCOND3,
-     $             DWORK(JWORK), IWORK, INFO )
-C
-      TOLL = TOL
-      IF( TOLL.LE.ZERO )
-     $   TOLL = MNOBRN*MNOBRN*EPS
-      IF ( RCOND3.GT.MAX( TOLL, THRESH ) ) THEN
-C
-C        The triangular factor is considered to be of full rank.
-C        Solve for  V(m*s+1:m*s+n,:),  giving  [ A'  C' ].
-C
-         FULLR = .TRUE.
-         RANKM = MNOBRN
-         IF ( N4SID )
-     $      CALL DTRSM( 'Left', 'Upper', 'NoTranspose', 'NonUnit', N,
-     $                  NPL, ONE, R(NR2,NR2), LDR, R(NR2,NR4MN), LDR )
-      ELSE
-         FULLR = .FALSE.
-C
-C        Use QR factorization (with pivoting). For METH = 'N', save
-C        (and then restore) information about the QR factorization of
-C        Gam,  for later use. Note that  R_11  could be modified by
-C        MB03OD, but the corresponding part of  N  is also modified
-C        accordingly.
-C        Workspace: need   d*N+4*(M*NOBR+N)+1;
-C                   prefer d*N+3*(M*NOBR+N)+(M*NOBR+N+1)*NB.
-C
-         DO 20 I = 1, MNOBRN
-            IWORK(I) = 0
-   20    CONTINUE
-C
-         IF ( N4SID .AND. ( M.GT.0 .AND. WITHB ) )
-     $      CALL DLACPY( 'Full', LNOBR, N, R(NR2,1), LDR, R(NR4,1),
-     $                   LDR )
-         JWORK = ITAU + MNOBRN
-         CALL DLASET( 'Lower', MNOBRN-1, MNOBRN, ZERO, ZERO, R(2,1),
-     $                LDR )
-         CALL MB03OD( 'QR', MNOBRN, MNOBRN, R, LDR, IWORK, TOLL,
-     $                SVLMAX, DWORK(ITAU), RANKM, SVAL, DWORK(JWORK),
-     $                LDWORK-JWORK+1, IERR )
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C        Workspace: need   d*N+M*NOBR+N+N+L;
-C                   prefer d*N+M*NOBR+N+(N+L)*NB.
-C
-         CALL DORMQR( 'Left', 'Transpose', MNOBRN, NPL, MNOBRN,
-     $                R, LDR, DWORK(ITAU), R(1,NR4MN), LDR,
-     $                DWORK(JWORK), LDWORK-JWORK+1, IERR )
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-      END IF
-C
-      IF ( WITHCO ) THEN
-C
-C        The residual (transposed) of the least squares solution
-C        (multiplied by a matrix with orthogonal columns) is stored
-C        in the rows  RANKM+1:(2*m+L)*s+L  of V,  and it should be
-C        squared-up for getting the covariance matrices. (Generically,
-C        RANKM = m*s+n.)
-C
-         RNRM = ONE/DBLE( NSMPL )
-         IF ( MOESP ) THEN
-            CALL DSYRK( 'Upper', 'Transpose', NPL, LMMNOL-RANKM, RNRM,
-     $                  R(RANKM+1,NR4MN), LDR, ZERO, R, LDR )
-            CALL DLACPY( 'Upper', N, N, R, LDR, Q, LDQ )
-            CALL DLACPY( 'Full',  N, L, R(1,N+1), LDR, S, LDS )
-            CALL DLACPY( 'Upper', L, L, R(N+1,N+1), LDR, RY, LDRY )
-         ELSE
-            CALL DSYRK( 'Upper', 'Transpose', NPL, LMMNOL-RANKM, RNRM,
-     $                  R(RANKM+1,NR4MN), LDR, ZERO, DWORK(JWORK), NPL )
-            CALL DLACPY( 'Upper', N, N, DWORK(JWORK), NPL, Q, LDQ )
-            CALL DLACPY( 'Full',  N, L, DWORK(JWORK+N*NPL), NPL, S,
-     $                   LDS )
-            CALL DLACPY( 'Upper', L, L, DWORK(JWORK+N*(NPL+1)), NPL, RY,
-     $                   LDRY )
-         END IF
-         CALL MA02ED( 'Upper', N, Q, LDQ )
-         CALL MA02ED( 'Upper', L, RY, LDRY )
-C
-C        Check the magnitude of the residual.
-C
-         RNRM = DLANGE( '1-norm', LMMNOL-RANKM, NPL, R(RANKM+1,NR4MN),
-     $                  LDR, DWORK(JWORK) )
-         IF ( RNRM.LT.THRESH )
-     $      IWARN = 5
-      END IF
-C
-      IF ( N4SID ) THEN
-         IF ( .NOT.FULLR ) THEN
-            IWARN = 4
-C
-C           Compute part of the solution of the least squares problem,
-C           M*V = N,  for the rank-deficient problem.
-C           Remark: this computation should not be performed before the
-C           symmetric updating operation above.
-C           Workspace: need   M*NOBR+3*N+L;
-C                      prefer larger.
-C
-            CALL MB03OD( 'No QR', N, N, R(NR2,NR2), LDR, IWORK, TOLL1,
-     $                   SVLMAX, DWORK(ITAU), RANKM, SVAL, DWORK(JWORK),
-     $                   LDWORK-JWORK+1, IERR )
-            CALL MB02QY( N, N, NPL, RANKM, R(NR2,NR2), LDR, IWORK,
-     $                   R(NR2,NR4MN), LDR, DWORK(ITAU+MNOBR),
-     $                   DWORK(JWORK), LDWORK-JWORK+1, INFO )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-            JWORK  = ITAU
-            IF ( M.GT.0 .AND. WITHB )
-     $         CALL DLACPY( 'Full', LNOBR, N, R(NR4,1), LDR, R(NR2,1),
-     $                      LDR )
-         END IF
-C
-         IF ( WITHC ) THEN
-C
-C           Obtain  A  and  C,  noting that block-permutations have been
-C           implicitly used.
-C
-            CALL MA02AD( 'Full', N, N, R(NR2,NR4MN), LDR, A, LDA )
-            CALL MA02AD( 'Full', N, L, R(NR2,NR4MN+N), LDR, C, LDC )
-         ELSE
-C
-C           Use the given  A  and  C.
-C
-            CALL MA02AD( 'Full', N, N, A, LDA, R(NR2,NR4MN), LDR )
-            CALL MA02AD( 'Full', L, N, C, LDC, R(NR2,NR4MN+N), LDR )
-         END IF
-C
-         IF ( M.GT.0 .AND. WITHB ) THEN
-C
-C           Obtain  B  and  D.
-C           First, compute the transpose of the matrix K as
-C           N(1:m*s,:) - M(1:m*s,m*s+1:m*s+n)*[A'  C'],  in the first
-C           m*s  rows of  R(1,NR4MN).
-C
-            CALL DGEMM ( 'NoTranspose', 'NoTranspose', MNOBR, NPL, N,
-     $                   -ONE, R(1,NR2), LDR, R(NR2,NR4MN), LDR, ONE,
-     $                   R(1,NR4MN), LDR )
-C
-C           Denote   M = pinv(GaL)  and construct
-C
-C                    [ [ A ]   -1   ]                      [ R ]
-C           and  L = [ [   ]  R   0 ] Q',  where Gam = Q * [   ].
-C                    [ [ C ]        ]                      [ 0 ]
-C
-C           Then, solve the least squares problem.
-C
-            CALL DLACPY( 'Full', N, N, A, LDA, R(NR2,NR4), LDR )
-            CALL DLACPY( 'Full', L, N, C, LDC, R(NR2+N,NR4), LDR )
-            CALL DTRSM(  'Right', 'Upper', 'NoTranspose', 'NonUnit',
-     $                   NPL, N, ONE, R(NR2,1), LDR, R(NR2,NR4), LDR )
-            CALL DLASET( 'Full', NPL, LNOBRN, ZERO, ZERO, R(NR2,NR4+N),
-     $                   LDR )
-C
-C           Workspace: need 2*N+L; prefer N + (N+L)*NB.
-C
-            CALL DORMQR( 'Right', 'Transpose', NPL, LNOBR, N, R(NR2,1),
-     $                   LDR, DWORK, R(NR2,NR4), LDR, DWORK(JWORK),
-     $                   LDWORK-JWORK+1, IERR )
-C
-C           Obtain the matrix  K  by transposition, and find  B  and  D.
-C           Workspace: need   NOBR*(M*(N+L))**2+M*NOBR*(N+L)+
-C                             max((N+L)**2,4*M*(N+L)+1);
-C                      prefer larger.
-C
-            CALL MA02AD( 'Full', MNOBR, NPL, R(1,NR4MN), LDR,
-     $                   R(NR2,NR3), LDR )
-            IX    = MNOBR*NPL**2*M + 1
-            JWORK = IX + MNOBR*NPL
-            CALL IB01PX( JOBPY, NOBR, N, M, L, R, LDR, O, LDO,
-     $                   R(NR2,NR4), LDR, R(NR4PL,NR2), LDR, R(NR2,NR3),
-     $                   LDR, DWORK, MNOBR*NPL, DWORK(IX), B, LDB, D,
-     $                   LDD, TOL, IWORK, DWORK(JWORK), LDWORK-JWORK+1,
-     $                   IWARNL, INFO )
-            IF ( INFO.NE.0 )
-     $         RETURN
-            IWARN  = MAX( IWARN, IWARNL )
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-            RCOND4 = DWORK(JWORK+1)
-C
-         END IF
-      END IF
-C
-   30 CONTINUE
-C
-C     Return optimal workspace in  DWORK(1)  and reciprocal condition
-C     numbers in the next locations.
-C
-      DWORK(1) = MAXWRK
-      DWORK(2) = RCOND1
-      DWORK(3) = RCOND2
-      DWORK(4) = RCOND3
-      DWORK(5) = RCOND4
-      RETURN
-C
-C *** Last line of IB01PD ***
-      END
--- a/extra/control-devel/src/IB01PX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,474 +0,0 @@
-      SUBROUTINE IB01PX( JOB, NOBR, N, M, L, UF, LDUF, UN, LDUN, UL,
-     $                   LDUL, PGAL, LDPGAL, K, LDK, R, LDR, X, B, LDB,
-     $                   D, LDD, TOL, IWORK, DWORK, LDWORK, IWARN,
-     $                   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 build and solve the least squares problem  T*X = Kv,  and
-C     estimate the matrices B and D of a linear time-invariant (LTI)
-C     state space model, using the solution  X,  and the singular
-C     value decomposition information and other intermediate results,
-C     provided by other routines.
-C
-C     The matrix  T  is computed as a sum of Kronecker products,
-C
-C        T = T + kron(Uf(:,(i-1)*m+1:i*m),N_i),  for i = 1 : s,
-C
-C     (with  T  initialized by zero), where  Uf  is the triangular
-C     factor of the QR factorization of the future input part (see
-C     SLICOT Library routine IB01ND),  N_i  is given by the i-th block
-C     row of the matrix
-C
-C            [ Q_11  Q_12  ...  Q_1,s-2  Q_1,s-1  Q_1s ]   [ I_L  0  ]
-C            [ Q_12  Q_13  ...  Q_1,s-1    Q_1s    0   ]   [         ]
-C        N = [ Q_13  Q_14  ...    Q_1s      0      0   ] * [         ],
-C            [  :     :            :        :      :   ]   [         ]
-C            [ Q_1s   0    ...     0        0      0   ]   [  0  GaL ]
-C
-C     and where
-C
-C               [   -L_1|1    ]          [ M_i-1 - L_1|i ]
-C        Q_11 = [             ],  Q_1i = [               ],  i = 2:s,
-C               [ I_L - L_2|1 ]          [     -L_2|i    ]
-C
-C     are  (n+L)-by-L  matrices, and  GaL  is built from the first  n
-C     relevant singular vectors,  GaL = Un(1:L(s-1),1:n),  computed
-C     by IB01ND.
-C
-C     The vector  Kv  is vec(K), with the matrix  K  defined by
-C
-C        K = [ K_1  K_2  K_3  ...  K_s ],
-C
-C     where  K_i = K(:,(i-1)*m+1:i*m),  i = 1:s,  is  (n+L)-by-m.
-C     The given matrices are  Uf,  GaL,  and
-C
-C            [ L_1|1  ...  L_1|s ]
-C        L = [                   ],   (n+L)-by-L*s,
-C            [ L_2|1  ...  L_2|s ]
-C
-C        M = [ M_1  ...  M_s-1 ],      n-by-L*(s-1),  and
-C        K,                            (n+L)-by-m*s.
-C
-C     Matrix  M  is the pseudoinverse of the matrix  GaL,  computed by
-C     SLICOT Library routine IB01PD.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies which of the matrices B and D should be
-C             computed, as follows:
-C             = 'B':  compute the matrix B, but not the matrix D;
-C             = 'D':  compute both matrices B and D.
-C
-C     Input/Output Parameters
-C
-C     NOBR    (input) INTEGER
-C             The number of block rows,  s,  in the input and output
-C             Hankel matrices processed by other routines.  NOBR > 1.
-C
-C     N       (input) INTEGER
-C             The order of the system.  NOBR > N > 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     UF      (input/output) DOUBLE PRECISION array, dimension
-C             ( LDUF,M*NOBR )
-C             On entry, the leading  M*NOBR-by-M*NOBR  upper triangular
-C             part of this array must contain the upper triangular
-C             factor of the QR factorization of the future input part,
-C             as computed by SLICOT Library routine IB01ND.
-C             The strict lower triangle need not be set to zero.
-C             On exit, the leading  M*NOBR-by-M*NOBR  upper triangular
-C             part of this array is unchanged, and the strict lower
-C             triangle is set to zero.
-C
-C     LDUF    INTEGER
-C             The leading dimension of the array  UF.
-C             LDUF >= MAX( 1, M*NOBR ).
-C
-C     UN      (input) DOUBLE PRECISION array, dimension ( LDUN,N )
-C             The leading  L*(NOBR-1)-by-N  part of this array must
-C             contain the matrix  GaL,  i.e., the leading part of the
-C             first  N  columns of the matrix  Un  of relevant singular
-C             vectors.
-C
-C     LDUN    INTEGER
-C             The leading dimension of the array  UN.
-C             LDUN >= L*(NOBR-1).
-C
-C     UL      (input/output) DOUBLE PRECISION array, dimension
-C             ( LDUL,L*NOBR )
-C             On entry, the leading  (N+L)-by-L*NOBR  part of this array
-C             must contain the given matrix  L.
-C             On exit, if  M > 0,  the leading  (N+L)-by-L*NOBR  part of
-C             this array is overwritten by the matrix
-C             [ Q_11  Q_12  ...  Q_1,s-2  Q_1,s-1  Q_1s ].
-C
-C     LDUL    INTEGER
-C             The leading dimension of the array  UL.  LDUL >= N+L.
-C
-C     PGAL    (input) DOUBLE PRECISION array, dimension
-C             ( LDPGAL,L*(NOBR-1) )
-C             The leading  N-by-L*(NOBR-1)  part of this array must
-C             contain the pseudoinverse of the matrix  GaL,  computed by
-C             SLICOT Library routine IB01PD.
-C
-C     LDPGAL  INTEGER
-C             The leading dimension of the array  PGAL.  LDPGAL >= N.
-C
-C     K       (input) DOUBLE PRECISION array, dimension ( LDK,M*NOBR )
-C             The leading  (N+L)-by-M*NOBR  part of this array must
-C             contain the given matrix  K.
-C
-C     LDK     INTEGER
-C             The leading dimension of the array  K.  LDK >= N+L.
-C
-C     R       (output) DOUBLE PRECISION array, dimension ( LDR,M*(N+L) )
-C             The leading  (N+L)*M*NOBR-by-M*(N+L)  part of this array
-C             contains details of the complete orthogonal factorization
-C             of the coefficient matrix  T  of the least squares problem
-C             which is solved for getting the system matrices B and D.
-C
-C     LDR     INTEGER
-C             The leading dimension of the array  R.
-C             LDR >= MAX( 1, (N+L)*M*NOBR ).
-C
-C     X       (output) DOUBLE PRECISION array, dimension
-C             ( (N+L)*M*NOBR )
-C             The leading  M*(N+L)  elements of this array contain the
-C             least squares solution of the system  T*X = Kv.
-C             The remaining elements are used as workspace (to store the
-C             corresponding part of the vector Kv = vec(K)).
-C
-C     B       (output) DOUBLE PRECISION array, dimension ( LDB,M )
-C             The leading N-by-M part of this array contains the system
-C             input matrix.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.  LDB >= N.
-C
-C     D       (output) DOUBLE PRECISION array, dimension ( LDD,M )
-C             If  JOB = 'D',  the leading L-by-M part of this array
-C             contains the system input-output matrix.
-C             If  JOB = 'B',  this array is not referenced.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.
-C             LDD >= L, if  JOB = 'D';
-C             LDD >= 1, if  JOB = 'B'.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used for estimating the rank of
-C             matrices. If the user sets  TOL > 0,  then the given value
-C             of  TOL  is used as a lower bound for the reciprocal
-C             condition number;  an m-by-n matrix whose estimated
-C             condition number is less than  1/TOL  is considered to
-C             be of full rank.  If the user sets  TOL <= 0,  then an
-C             implicitly computed, default tolerance, defined by
-C             TOLDEF = m*n*EPS,  is used instead, where  EPS  is the
-C             relative machine precision (see LAPACK Library routine
-C             DLAMCH).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension ( M*(N+L) )
-C
-C     DWORK   DOUBLE PRECISION array, dimension ( LDWORK )
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of LDWORK,  and, if  M > 0,  DWORK(2)  contains the
-C             reciprocal condition number of the triangular factor of
-C             the matrix  T.
-C             On exit, if  INFO = -26,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX( (N+L)*(N+L), 4*M*(N+L)+1 ).
-C             For good performance,  LDWORK  should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 4:  the least squares problem to be solved has a
-C                   rank-deficient coefficient matrix.
-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     METHOD
-C
-C     The matrix  T  is computed, evaluating the sum of Kronecker
-C     products, and then the linear system  T*X = Kv  is solved in a
-C     least squares sense. The matrices  B  and  D  are then directly
-C     obtained from the least squares solution.
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Dewilde, P.
-C         Subspace Model Identification. Part 1: The output-error
-C         state-space model identification class of algorithms.
-C         Int. J. Control, 56, pp. 1187-1210, 1992.
-C
-C     [2] Van Overschee, P., and De Moor, B.
-C         N4SID: Two Subspace Algorithms for the Identification
-C         of Combined Deterministic-Stochastic Systems.
-C         Automatica, Vol.30, No.1, pp. 75-93, 1994.
-C
-C     [3] Van Overschee, P.
-C         Subspace Identification : Theory - Implementation -
-C         Applications.
-C         Ph. D. Thesis, Department of Electrical Engineering,
-C         Katholieke Universiteit Leuven, Belgium, Feb. 1995.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is numerically stable.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Universiteit Leuven, Feb. 2000.
-C
-C     REVISIONS
-C
-C     V. Sima, Katholieke Universiteit Leuven, Sep. 2001.
-C
-C     KEYWORDS
-C
-C     Identification methods; least squares solutions; multivariable
-C     systems; QR decomposition; singular value decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO  = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   TOL
-      INTEGER            INFO, IWARN, L, LDB, LDD, LDK, LDPGAL, LDR,
-     $                   LDUF, LDUL, LDUN, LDWORK, M, N, NOBR
-      CHARACTER          JOB
-C     .. Array Arguments ..
-      DOUBLE PRECISION   B(LDB, *), D(LDD, *), DWORK(*), K(LDK, *),
-     $                   PGAL(LDPGAL, *), R(LDR, *), UF(LDUF, *),
-     $                   UL(LDUL, *), UN(LDUN, *), X(*)
-      INTEGER            IWORK( * )
-C     .. Local Scalars ..
-      DOUBLE PRECISION   RCOND, TOLL
-      INTEGER            I, IERR, J, JWORK, LDUN2, LNOBR, LP1, MAXWRK,
-     $                   MINWRK, MKRON, MNOBR, NKRON, NP1, NPL, RANK
-      LOGICAL            WITHB, WITHD
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DGELSY, DGEMM, DLACPY, DLASET, DTRCON, MB01VD,
-     $                   XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX
-C     .. Executable Statements ..
-C
-C     Decode the scalar input parameters.
-C
-      WITHD = LSAME( JOB, 'D' )
-      WITHB = LSAME( JOB, 'B' ) .OR. WITHD
-      MNOBR = M*NOBR
-      LNOBR = L*NOBR
-      LDUN2 = LNOBR - L
-      LP1   = L + 1
-      NP1   = N + 1
-      NPL   = N + L
-      IWARN = 0
-      INFO  = 0
-C
-C     Check the scalar input parameters.
-C
-      IF( .NOT.WITHB ) THEN
-         INFO = -1
-      ELSE IF( NOBR.LE.1 ) THEN
-         INFO = -2
-      ELSE IF( N.GE.NOBR .OR. N.LE.0 ) THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( L.LE.0 ) THEN
-         INFO = -5
-      ELSE IF( LDUF.LT.MAX( 1, MNOBR ) ) THEN
-         INFO = -7
-      ELSE IF( LDUN.LT.LDUN2 ) THEN
-         INFO = -9
-      ELSE IF( LDUL.LT.NPL ) THEN
-         INFO = -11
-      ELSE IF( LDPGAL.LT.N ) THEN
-         INFO = -13
-      ELSE IF( LDK.LT.NPL ) THEN
-         INFO = -15
-      ELSE IF( LDR.LT.MAX( 1, MNOBR*NPL ) ) THEN
-         INFO = -17
-      ELSE IF( LDB.LT.N ) THEN
-         INFO = -20
-      ELSE IF( LDD.LT.1 .OR. ( WITHD .AND. LDD.LT.L ) ) THEN
-         INFO = -22
-      ELSE
-C
-C        Compute workspace.
-C        (Note: Comments in the code beginning "Workspace:" describe the
-C         minimal amount of workspace needed at that point in the code,
-C         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
-         MINWRK = MAX( NPL*NPL, 4*M*NPL + 1 )
-C
-         IF ( LDWORK.LT.MINWRK ) THEN
-            INFO = -26
-            DWORK( 1 ) = MINWRK
-         END IF
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01PX', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( M.EQ.0 ) THEN
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Construct the matrix  [ Q_11  Q_12  ...  Q_1,s-1  Q_1s ]  in  UL.
-C
-      DO 20 J = 1, L
-C
-         DO 10 I = 1, NPL
-            UL(I,J) = -UL(I,J)
-   10    CONTINUE
-C
-         UL(N+J,J) = ONE + UL(N+J,J)
-   20 CONTINUE
-C
-      DO 50 J = LP1, LNOBR
-C
-         DO 30 I = 1, N
-            UL(I,J) = PGAL(I,J-L) - UL(I,J)
-   30    CONTINUE
-C
-         DO 40 I = NP1, NPL
-            UL(I,J) = -UL(I,J)
-   40    CONTINUE
-C
-   50 CONTINUE
-C
-C     Compute the coefficient matrix T using Kronecker products.
-C     Workspace: (N+L)*(N+L).
-C     In the same loop, vectorize K in X.
-C
-      CALL DLASET( 'Full', MNOBR*NPL, M*NPL, ZERO, ZERO, R, LDR )
-      CALL DLASET( 'Lower', MNOBR-1, MNOBR-1, ZERO, ZERO, UF(2,1),
-     $             LDUF )
-      JWORK = NPL*L + 1
-C
-      DO 60 I = 1, NOBR
-         CALL DLACPY( 'Full', NPL, L, UL(1,(I-1)*L+1), LDUL, DWORK,
-     $                NPL )
-         IF ( I.LT.NOBR ) THEN
-            CALL DGEMM ( 'NoTranspose', 'NoTranspose', NPL, N,
-     $                   L*(NOBR-I), ONE, UL(1,I*L+1), LDUL, UN, LDUN,
-     $                   ZERO, DWORK(JWORK), NPL )
-         ELSE
-            CALL DLASET( 'Full', NPL, N, ZERO, ZERO, DWORK(JWORK), NPL )
-         END IF
-         CALL MB01VD( 'NoTranspose', 'NoTranspose', MNOBR, M, NPL,
-     $                NPL, ONE, ONE, UF(1,(I-1)*M+1), LDUF, DWORK,
-     $                NPL, R, LDR, MKRON, NKRON, IERR )
-         CALL DLACPY( 'Full', NPL, M, K(1,(I-1)*M+1), LDK,
-     $                X((I-1)*NKRON+1), NPL )
-   60 CONTINUE
-C
-C     Compute the tolerance.
-C
-      TOLL = TOL
-      IF( TOLL.LE.ZERO )
-     $   TOLL = MKRON*NKRON*DLAMCH( 'Precision' )
-C
-C     Solve the least square problem  T*X = vec(K).
-C     Workspace:  need   4*M*(N+L)+1;
-C                 prefer 3*M*(N+L)+(M*(N+L)+1)*NB.
-C
-      DO 70 I = 1, NKRON
-         IWORK(I) = 0
-   70 CONTINUE
-C
-      CALL DGELSY( MKRON, NKRON, 1, R, LDR, X, MKRON, IWORK, TOLL, RANK,
-     $             DWORK, LDWORK, IERR )
-      MAXWRK = DWORK(1)
-C
-C     Compute the reciprocal of the condition number of the triangular
-C     factor  R  of  T.
-C     Workspace: need 3*M*(N+L).
-C
-      CALL DTRCON( '1-norm', 'Upper', 'NonUnit', NKRON, R, LDR, RCOND,
-     $             DWORK, IWORK, IERR )
-C
-      IF ( RANK.LT.NKRON ) THEN
-C
-C        The least squares problem is rank-deficient.
-C
-         IWARN = 4
-      END IF
-C
-C     Construct the matrix  D,  if needed.
-C
-      IF ( WITHD )
-     $   CALL DLACPY( 'Full', L, M, X, NPL, D, LDD )
-C
-C     Construct the matrix  B.
-C
-      CALL DLACPY( 'Full', N, M, X(LP1), NPL, B, LDB )
-C
-C     Return optimal workspace in DWORK(1) and reciprocal condition
-C     number in  DWORK(2).
-C
-      DWORK(1) = MAX( MINWRK, MAXWRK )
-      DWORK(2) = RCOND
-C
-      RETURN
-C
-C *** Last line of IB01PX ***
-      END
--- a/extra/control-devel/src/IB01PY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,768 +0,0 @@
-      SUBROUTINE IB01PY( METH, JOB, NOBR, N, M, L, RANKR1, UL, LDUL,
-     $                   R1, LDR1, TAU1, PGAL, LDPGAL, K, LDK, R, LDR,
-     $                   H, LDH, B, LDB, D, LDD, TOL, IWORK, DWORK,
-     $                   LDWORK, IWARN, 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     1. To compute the triangular  (QR)  factor of the  p-by-L*s
-C     structured matrix  Q,
-C
-C         [ Q_1s  Q_1,s-1  Q_1,s-2  ...  Q_12  Q_11 ]
-C         [  0      Q_1s   Q_1,s-1  ...  Q_13  Q_12 ]
-C     Q = [  0       0       Q_1s   ...  Q_14  Q_13 ],
-C         [  :       :        :           :     :   ]
-C         [  0       0        0     ...   0    Q_1s ]
-C
-C     and apply the transformations to the p-by-m matrix  Kexpand,
-C
-C               [ K_1 ]
-C               [ K_2 ]
-C     Kexpand = [ K_3 ],
-C               [  :  ]
-C               [ K_s ]
-C
-C     where, for MOESP approach (METH = 'M'), p = s*(L*s-n), and
-C     Q_1i = u2(L*(i-1)+1:L*i,:)'  is  (Ls-n)-by-L,  for  i = 1:s,
-C     u2 = Un(1:L*s,n+1:L*s),  K_i = K(:,(i-1)*m+1:i*m)  (i = 1:s)
-C     is  (Ls-n)-by-m, and for N4SID approach (METH = 'N'), p = s*(n+L),
-C     and
-C
-C               [   -L_1|1    ]          [ M_i-1 - L_1|i ]
-C        Q_11 = [             ],  Q_1i = [               ],  i = 2:s,
-C               [ I_L - L_2|1 ]          [     -L_2|i    ]
-C
-C     are  (n+L)-by-L  matrices, and
-C     K_i = K(:,(i-1)*m+1:i*m),  i = 1:s,  is  (n+L)-by-m.
-C     The given matrices are:
-C     For  METH = 'M',  u2 = Un(1:L*s,n+1:L*s),
-C                       K(1:Ls-n,1:m*s);
-C
-C                           [ L_1|1  ...  L_1|s ]
-C     For  METH = 'N',  L = [                   ],   (n+L)-by-L*s,
-C                           [ L_2|1  ...  L_2|s ]
-C
-C                       M = [ M_1  ...  M_s-1 ],  n-by-L*(s-1),  and
-C                       K,                        (n+L)-by-m*s.
-C                       Matrix M is the pseudoinverse of the matrix GaL,
-C                       built from the first  n  relevant singular
-C                       vectors,  GaL = Un(1:L(s-1),1:n),  and computed
-C                       by SLICOT Library routine IB01PD for METH = 'N'.
-C
-C     Matrix  Q  is triangularized  (in  R),  exploiting its structure,
-C     and the transformations are applied from the left to  Kexpand.
-C
-C     2. To estimate the matrices B and D of a linear time-invariant
-C     (LTI) state space model, using the factor  R,  transformed matrix
-C     Kexpand, and the singular value decomposition information provided
-C     by other routines.
-C
-C     IB01PY  routine is intended for speed and efficient use of the
-C     memory space. It is generally not recommended for  METH = 'N',  as
-C     IB01PX  routine can produce more accurate results.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     METH    CHARACTER*1
-C             Specifies the subspace identification method to be used,
-C             as follows:
-C             = 'M':  MOESP  algorithm with past inputs and outputs;
-C             = 'N':  N4SID  algorithm.
-C
-C     JOB     CHARACTER*1
-C             Specifies whether or not the matrices B and D should be
-C             computed, as follows:
-C             = 'B':  compute the matrix B, but not the matrix D;
-C             = 'D':  compute both matrices B and D;
-C             = 'N':  do not compute the matrices B and D, but only the
-C                     R  factor of  Q  and the transformed Kexpand.
-C
-C     Input/Output Parameters
-C
-C     NOBR    (input) INTEGER
-C             The number of block rows,  s,  in the input and output
-C             Hankel matrices processed by other routines.  NOBR > 1.
-C
-C     N       (input) INTEGER
-C             The order of the system.  NOBR > N > 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     RANKR1  (input) INTEGER
-C             The effective rank of the upper triangular matrix  r1,
-C             i.e., the triangular QR factor of the matrix  GaL,
-C             computed by SLICOT Library routine IB01PD. It is also
-C             the effective rank of the matrix  GaL.  0 <= RANKR1 <= N.
-C             If  JOB = 'N',  or  M = 0,  or  METH = 'N',  this
-C             parameter is not used.
-C
-C     UL      (input/workspace) DOUBLE PRECISION array, dimension
-C             ( LDUL,L*NOBR )
-C             On entry, if  METH = 'M',  the leading  L*NOBR-by-L*NOBR
-C             part of this array must contain the matrix  Un  of
-C             relevant singular vectors. The first  N  columns of  UN
-C             need not be specified for this routine.
-C             On entry, if  METH = 'N',  the leading  (N+L)-by-L*NOBR
-C             part of this array must contain the given matrix  L.
-C             On exit, the leading  LDF-by-L*(NOBR-1) part of this array
-C             is overwritten by the matrix  F  of the algorithm in [4],
-C             where  LDF = MAX( 1, L*NOBR-N-L ), if  METH = 'M';
-C                    LDF = N,                    if  METH = 'N'.
-C
-C     LDUL    INTEGER
-C             The leading dimension of the array  UL.
-C             LDUL >= L*NOBR, if  METH = 'M';
-C             LDUL >= N+L,    if  METH = 'N'.
-C
-C     R1      (input) DOUBLE PRECISION array, dimension ( LDR1,N )
-C             If  JOB <> 'N',  M > 0,  METH = 'M',  and  RANKR1 = N,
-C             the leading  L*(NOBR-1)-by-N  part of this array must
-C             contain details of the QR factorization of the matrix
-C             GaL,  as computed by SLICOT Library routine IB01PD.
-C             Specifically, the leading N-by-N upper triangular part
-C             must contain the upper triangular factor  r1  of  GaL,
-C             and the lower  L*(NOBR-1)-by-N  trapezoidal part, together
-C             with array TAU1, must contain the factored form of the
-C             orthogonal matrix  Q1  in the QR factorization of  GaL.
-C             If  JOB = 'N',  or  M = 0,  or  METH = 'N', or  METH = 'M'
-C             and  RANKR1 < N,  this array is not referenced.
-C
-C     LDR1    INTEGER
-C             The leading dimension of the array  R1.
-C             LDR1 >= L*(NOBR-1), if  JOB <> 'N',  M > 0,  METH = 'M',
-C                                 and  RANKR1 = N;
-C             LDR1 >= 1,          otherwise.
-C
-C     TAU1    (input) DOUBLE PRECISION array, dimension ( N )
-C             If  JOB <> 'N',  M > 0,  METH = 'M',  and  RANKR1 = N,
-C             this array must contain the scalar factors of the
-C             elementary reflectors used in the QR factorization of the
-C             matrix  GaL,  computed by SLICOT Library routine IB01PD.
-C             If  JOB = 'N',  or  M = 0,  or  METH = 'N', or  METH = 'M'
-C             and  RANKR1 < N,  this array is not referenced.
-C
-C     PGAL    (input) DOUBLE PRECISION array, dimension
-C             ( LDPGAL,L*(NOBR-1) )
-C             If  METH = 'N',  or  JOB <> 'N',  M > 0,  METH = 'M'  and
-C             RANKR1 < N,  the leading  N-by-L*(NOBR-1)  part of this
-C             array must contain the pseudoinverse of the matrix  GaL,
-C             as computed by SLICOT Library routine IB01PD.
-C             If  METH = 'M'  and  JOB = 'N',  or  M = 0,  or
-C             RANKR1 = N,  this array is not referenced.
-C
-C     LDPGAL  INTEGER
-C             The leading dimension of the array  PGAL.
-C             LDPGAL >= N,  if   METH = 'N',  or  JOB <> 'N',  M > 0,
-C                           and  METH = 'M'  and RANKR1 < N;
-C             LDPGAL >= 1,  otherwise.
-C
-C     K       (input/output) DOUBLE PRECISION array, dimension
-C             ( LDK,M*NOBR )
-C             On entry, the leading  (p/s)-by-M*NOBR  part of this array
-C             must contain the given matrix  K  defined above.
-C             On exit, the leading  (p/s)-by-M*NOBR  part of this array
-C             contains the transformed matrix  K.
-C
-C     LDK     INTEGER
-C             The leading dimension of the array  K.  LDK >= p/s.
-C
-C     R       (output) DOUBLE PRECISION array, dimension ( LDR,L*NOBR )
-C             If  JOB = 'N',  or  M = 0,  or  Q  has full rank, the
-C             leading  L*NOBR-by-L*NOBR  upper triangular part of this
-C             array contains the  R  factor of the QR factorization of
-C             the matrix  Q.
-C             If  JOB <> 'N',  M > 0,  and  Q  has not a full rank, the
-C             leading  L*NOBR-by-L*NOBR  upper trapezoidal part of this
-C             array contains details of the complete orhogonal
-C             factorization of the matrix  Q,  as constructed by SLICOT
-C             Library routines MB03OD and MB02QY.
-C
-C     LDR     INTEGER
-C             The leading dimension of the array  R.  LDR >= L*NOBR.
-C
-C     H       (output) DOUBLE PRECISION array, dimension ( LDH,M )
-C             If  JOB = 'N'  or  M = 0,  the leading  L*NOBR-by-M  part
-C             of this array contains the updated part of the matrix
-C             Kexpand  corresponding to the upper triangular factor  R
-C             in the QR factorization of the matrix  Q.
-C             If  JOB <> 'N',  M > 0,  and  METH = 'N'  or  METH = 'M'
-C             and  RANKR1 < N,  the leading  L*NOBR-by-M  part of this
-C             array contains the minimum norm least squares solution of
-C             the linear system  Q*X = Kexpand,  from which the matrices
-C             B  and  D  are found. The first  NOBR-1  row blocks of  X
-C             appear in the reverse order in  H.
-C             If  JOB <> 'N',  M > 0,  METH = 'M'  and  RANKR1 = N,  the
-C             leading  L*(NOBR-1)-by-M  part of this array contains the
-C             matrix product  Q1'*X,  and the subarray
-C             L*(NOBR-1)+1:L*NOBR-by-M  contains the  corresponding
-C             submatrix of  X,  with  X  defined in the phrase above.
-C
-C     LDH     INTEGER
-C             The leading dimension of the array  H.  LDH >= L*NOBR.
-C
-C     B       (output) DOUBLE PRECISION array, dimension ( LDB,M )
-C             If  M > 0,  JOB = 'B' or 'D'  and  INFO = 0,  the leading
-C             N-by-M part of this array contains the system input
-C             matrix.
-C             If  M = 0  or  JOB = 'N',  this array is not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.
-C             LDB >= N, if  M > 0 and JOB = 'B' or 'D';
-C             LDB >= 1, if  M = 0 or  JOB = 'N'.
-C
-C     D       (output) DOUBLE PRECISION array, dimension ( LDD,M )
-C             If  M > 0,  JOB = 'D'  and  INFO = 0,  the leading
-C             L-by-M part of this array contains the system input-output
-C             matrix.
-C             If  M = 0  or  JOB = 'B'  or  'N',  this array is not
-C             referenced.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.
-C             LDD >= L, if  M > 0 and JOB = 'D';
-C             LDD >= 1, if  M = 0 or  JOB = 'B' or 'N'.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used for estimating the rank of
-C             matrices. If the user sets  TOL > 0,  then the given value
-C             of  TOL  is used as a lower bound for the reciprocal
-C             condition number;  an m-by-n matrix whose estimated
-C             condition number is less than  1/TOL  is considered to
-C             be of full rank.  If the user sets  TOL <= 0,  then an
-C             implicitly computed, default tolerance, defined by
-C             TOLDEF = m*n*EPS,  is used instead, where  EPS  is the
-C             relative machine precision (see LAPACK Library routine
-C             DLAMCH).
-C             This parameter is not used if  M = 0  or  JOB = 'N'.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension ( LIWORK )
-C             where  LIWORK >= 0,       if  JOB =  'N',  or   M = 0;
-C                    LIWORK >= L*NOBR,  if  JOB <> 'N',  and  M > 0.
-C
-C     DWORK   DOUBLE PRECISION array, dimension ( LDWORK )
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of  LDWORK,  and, if  JOB <> 'N',  and  M > 0,  DWORK(2)
-C             contains the reciprocal condition number of the triangular
-C             factor of the matrix  R.
-C             On exit, if  INFO = -28,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX( 2*L, L*NOBR, L+M*NOBR ),
-C                                         if  JOB = 'N',  or  M = 0;
-C             LDWORK >= MAX( L+M*NOBR, L*NOBR + MAX( 3*L*NOBR+1, M ) ),
-C                                         if  JOB <> 'N',  and  M > 0.
-C             For good performance,  LDWORK  should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 4:  the least squares problem to be solved has a
-C                   rank-deficient coefficient matrix.
-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             = 3:  a singular upper triangular matrix was found.
-C
-C     METHOD
-C
-C     The QR factorization is computed exploiting the structure,
-C     as described in [4].
-C     The matrices  B  and  D  are then obtained by solving certain
-C     linear systems in a least squares sense.
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Dewilde, P.
-C         Subspace Model Identification. Part 1: The output-error
-C         state-space model identification class of algorithms.
-C         Int. J. Control, 56, pp. 1187-1210, 1992.
-C
-C     [2] Van Overschee, P., and De Moor, B.
-C         N4SID: Two Subspace Algorithms for the Identification
-C         of Combined Deterministic-Stochastic Systems.
-C         Automatica, Vol.30, No.1, pp. 75-93, 1994.
-C
-C     [3] Van Overschee, P.
-C         Subspace Identification : Theory - Implementation -
-C         Applications.
-C         Ph. D. Thesis, Department of Electrical Engineering,
-C         Katholieke Universiteit Leuven, Belgium, Feb. 1995.
-C
-C     [4] Sima, V.
-C         Subspace-based Algorithms for Multivariable System
-C         Identification.
-C         Studies in Informatics and Control, 5, pp. 335-344, 1996.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method for computing the triangular factor and
-C     updating Kexpand is numerically stable.
-C
-C     FURTHER COMMENTS
-C
-C     The computed matrices B and D are not the least squares solutions
-C     delivered by either MOESP or N4SID algorithms, except for the
-C     special case n = s - 1, L = 1. However, the computed B and D are
-C     frequently good enough estimates, especially for  METH = 'M'.
-C     Better estimates could be obtained by calling SLICOT Library
-C     routine IB01PX, but it is less efficient, and requires much more
-C     workspace.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 1999.
-C
-C     REVISIONS
-C
-C     Feb. 2000, Sep. 2001, March 2005.
-C
-C     KEYWORDS
-C
-C     Identification methods; least squares solutions; multivariable
-C     systems; QR decomposition; singular value decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, THREE
-      PARAMETER          ( ZERO  = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
-     $                     THREE = 3.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   TOL
-      INTEGER            INFO, IWARN, L, LDB, LDD, LDH, LDK, LDPGAL,
-     $                   LDR, LDR1, LDUL, LDWORK, M, N, NOBR, RANKR1
-      CHARACTER          JOB, METH
-C     .. Array Arguments ..
-      DOUBLE PRECISION   B(LDB, *), D(LDD, *), DWORK(*), H(LDH, *),
-     $                   K(LDK, *), PGAL(LDPGAL, *), R(LDR, *),
-     $                   R1(LDR1, *), TAU1(*), UL(LDUL, *)
-      INTEGER            IWORK( * )
-C     .. Local Scalars ..
-      DOUBLE PRECISION   EPS, RCOND, SVLMAX, THRESH, TOLL
-      INTEGER            I, IERR, ITAU, J, JI, JL, JM, JWORK, LDUN2,
-     $                   LNOBR, LP1, MAXWRK, MINWRK, MNOBR, NOBRH,
-     $                   NROW, NROWML, RANK
-      LOGICAL            MOESP, N4SID, WITHB, WITHD
-C     .. Local Array ..
-      DOUBLE PRECISION   SVAL(3)
-C     .. External Functions ..
-      LOGICAL            LSAME
-      INTEGER            ILAENV
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           DLAMCH, ILAENV, LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DGEMM, DGEQRF, DLACPY, DLASET, DORMQR, DSWAP,
-     $                   DTRCON, DTRSM, DTRTRS, MA02AD, MB02QY, MB03OD,
-     $                   MB04OD, MB04OY, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          INT, MAX, MOD
-C     .. Executable Statements ..
-C
-C     Decode the scalar input parameters.
-C
-      MOESP = LSAME( METH, 'M' )
-      N4SID = LSAME( METH, 'N' )
-      WITHD = LSAME( JOB,  'D' )
-      WITHB = LSAME( JOB,  'B' ) .OR. WITHD
-      MNOBR = M*NOBR
-      LNOBR = L*NOBR
-      LDUN2 = LNOBR - L
-      LP1   = L + 1
-      IF ( MOESP ) THEN
-         NROW = LNOBR - N
-      ELSE
-         NROW = N + L
-      END IF
-      NROWML = NROW - L
-      IWARN  = 0
-      INFO   = 0
-C
-C     Check the scalar input parameters.
-C
-      IF( .NOT.( MOESP .OR. N4SID ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( WITHB .OR. LSAME( JOB, 'N' ) ) ) THEN
-         INFO = -2
-      ELSE IF( NOBR.LE.1 ) THEN
-         INFO = -3
-      ELSE IF( N.GE.NOBR .OR. N.LE.0 ) THEN
-         INFO = -4
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( L.LE.0 ) THEN
-         INFO = -6
-      ELSE IF( ( MOESP .AND. WITHB .AND. M.GT.0 ) .AND.
-     $         ( RANKR1.LT.ZERO .OR. RANKR1.GT.N ) ) THEN
-         INFO = -7
-      ELSE IF( ( MOESP .AND. LDUL.LT.LNOBR ) .OR.
-     $         ( N4SID .AND. LDUL.LT.NROW ) ) THEN
-         INFO = -9
-      ELSE IF( LDR1.LT.1 .OR. ( M.GT.0 .AND. WITHB .AND. MOESP .AND.
-     $         LDR1.LT.LDUN2 .AND. RANKR1.EQ.N ) ) THEN
-         INFO = -11
-      ELSE IF( LDPGAL.LT.1 .OR.
-     $       ( LDPGAL.LT.N .AND. ( N4SID .OR. ( WITHB .AND. M.GT.0
-     $                     .AND. ( MOESP .AND. RANKR1.LT.N ) ) ) ) )
-     $      THEN
-         INFO = -14
-      ELSE IF( LDK.LT.NROW ) THEN
-         INFO = -16
-      ELSE IF( LDR.LT.LNOBR ) THEN
-         INFO = -18
-      ELSE IF( LDH.LT.LNOBR ) THEN
-         INFO = -20
-      ELSE IF( LDB.LT.1 .OR. ( M.GT.0 .AND. WITHB .AND. LDB.LT.N ) )
-     $      THEN
-         INFO = -22
-      ELSE IF( LDD.LT.1 .OR. ( M.GT.0 .AND. WITHD .AND. LDD.LT.L ) )
-     $      THEN
-         INFO = -24
-      ELSE
-C
-C        Compute workspace.
-C        (Note: Comments in the code beginning "Workspace:" describe the
-C         minimal amount of workspace needed at that point in the code,
-C         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
-         MINWRK = MAX( 2*L, LNOBR, L + MNOBR )
-         MAXWRK = MINWRK
-         MAXWRK = MAX( MAXWRK, L + L*ILAENV( 1, 'DGEQRF', ' ', NROW, L,
-     $                                      -1, -1 ) )
-         MAXWRK = MAX( MAXWRK, L + LDUN2*ILAENV( 1, 'DORMQR', 'LT',
-     $                                           NROW, LDUN2, L, -1 ) )
-         MAXWRK = MAX( MAXWRK, L + MNOBR*ILAENV( 1, 'DORMQR', 'LT',
-     $                                           NROW, MNOBR, L, -1 ) )
-C
-         IF( M.GT.0 .AND. WITHB ) THEN
-            MINWRK = MAX( MINWRK, 4*LNOBR+1, LNOBR + M )
-            MAXWRK = MAX( MINWRK, MAXWRK, LNOBR +
-     $                    M*ILAENV( 1, 'DORMQR', 'LT', LNOBR, M, LNOBR,
-     $                              -1 ) )
-         END IF
-C
-         IF ( LDWORK.LT.MINWRK ) THEN
-            INFO = -28
-            DWORK( 1 ) = MINWRK
-         END IF
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01PY', -INFO )
-         RETURN
-      END IF
-C
-C     Construct in  R  the first block-row of  Q,  i.e., the
-C     (p/s)-by-L*s  matrix  [ Q_1s  ...  Q_12  Q_11  ],  where
-C     Q_1i,  defined above, is  (p/s)-by-L,  for  i = 1:s.
-C
-      IF ( MOESP ) THEN
-C
-         DO 10 I = 1, NOBR
-            CALL MA02AD( 'Full', L, NROW, UL(L*(I-1)+1,N+1), LDUL,
-     $                    R(1,L*(NOBR-I)+1), LDR )
-   10    CONTINUE
-C
-      ELSE
-         JL = LNOBR
-         JM = LDUN2
-C
-         DO 50 JI = 1, LDUN2, L
-C
-            DO 40 J = JI + L - 1, JI, -1
-C
-               DO 20 I = 1, N
-                  R(I,J) = PGAL(I,JM) - UL(I,JL)
-   20          CONTINUE
-C
-               DO 30 I = N + 1, NROW
-                  R(I,J) = -UL(I,JL)
-   30          CONTINUE
-C
-               JL = JL - 1
-               JM = JM - 1
-   40       CONTINUE
-C
-   50    CONTINUE
-C
-         DO 70 J = LNOBR, LDUN2 + 1, -1
-C
-            DO 60 I = 1, NROW
-               R(I,J) = -UL(I,JL)
-   60       CONTINUE
-C
-            JL = JL - 1
-            R(N+J-LDUN2,J) = ONE + R(N+J-LDUN2,J)
-   70    CONTINUE
-      END IF
-C
-C     Triangularize the submatrix  Q_1s  using an orthogonal matrix  S.
-C     Workspace: need 2*L, prefer L+L*NB.
-C
-      ITAU  = 1
-      JWORK = ITAU + L
-C
-      CALL DGEQRF( NROW, L, R, LDR, DWORK(ITAU), DWORK(JWORK),
-     $             LDWORK-JWORK+1, IERR )
-C
-C     Apply the transformation  S'  to the matrix
-C     [ Q_1,s-1  ...  Q_11 ].  Therefore,
-C
-C                              [ R  P_s-1  P_s-2  ...  P_2  P_1 ]
-C     S'[ Q_1,s  ...  Q_11 ] = [                                ].
-C                              [ 0  F_s-1  F_s-2  ...  F_2  F_1 ]
-C
-C     Workspace: need L*NOBR, prefer L+(L*NOBR-L)*NB.
-C
-      CALL DORMQR( 'Left', 'Transpose', NROW, LDUN2, L, R, LDR,
-     $             DWORK(ITAU), R(1,LP1), LDR, DWORK(JWORK),
-     $             LDWORK-JWORK+1, IERR )
-C
-C     Apply the transformation  S'  to each of the submatrices  K_i  of
-C     Kexpand = [ K_1'  K_2'  ...  K_s' ]',  K_i = K(:,(i-1)*m+1:i*m)
-C     (i = 1:s)  being  (p/s)-by-m.  Denote  ( H_i'  G_i' )' = S'K_i
-C     (i = 1:s),  where  H_i  has  L  rows.
-C     Finally,  H_i  is saved in  H(L*(i-1)+1:L*i,1:m), i = 1:s.
-C     (G_i  is in  K(L+1:p/s,(i-1)*m+1:i*m),  i = 1:s.)
-C     Workspace: need L+M*NOBR, prefer L+M*NOBR*NB.
-C
-      CALL DORMQR( 'Left', 'Transpose', NROW, MNOBR, L, R, LDR,
-     $             DWORK(ITAU), K, LDK, DWORK(JWORK), LDWORK-JWORK+1,
-     $             IERR )
-C
-C     Put the rows to be annihilated (matrix F) in  UL(1:p/s-L,1:L*s-L).
-C
-      CALL DLACPY( 'Full', NROWML, LDUN2, R(LP1,LP1), LDR, UL, LDUL )
-C
-C     Now, the structure of the transformed matrices is:
-C
-C         [  R   P_s-1  P_s-2  ...  P_2  P_1  ]             [  H_1  ]
-C         [  0     R    P_s-1  ...  P_3  P_2  ]             [  H_2  ]
-C         [  0     0      R    ...  P_4  P_3  ]             [  H_3  ]
-C         [  :     :      :          :    :   ]             [   :   ]
-C         [  0     0      0    ...   R  P_s-1 ]             [ H_s-1 ]
-C     Q = [  0     0      0     ...  0    R   ],  Kexpand = [  H_s  ],
-C         [  0   F_s-1  F_s-2  ...  F_2  F_1  ]             [  G_1  ]
-C         [  0     0    F_s-1  ...  F_3  F_2  ]             [  G_2  ]
-C         [  :     :      :          :    :   ]             [   :   ]
-C         [  0     0      0     ...  0  F_s-1 ]             [ G_s-1 ]
-C         [  0     0      0     ...  0    0   ]             [  G_s  ]
-C
-C     where the block-rows have been permuted, to better exploit the
-C     structure. The block-rows having  R  on the diagonal are dealt
-C     with successively in the array  R.
-C     The  F  submatrices are stored in the array  UL,  as a block-row.
-C
-C     Copy  H_1  in  H(1:L,1:m).
-C
-      CALL DLACPY( 'Full', L, M, K, LDK, H, LDH )
-C
-C     Triangularize the transformed matrix exploiting its structure.
-C     Workspace: need L+MAX(L-1,L*NOBR-2*L,M*(NOBR-1)).
-C
-      DO 90 I = 1, NOBR - 1
-C
-C        Copy part of the preceding block-row and then annihilate the
-C        current submatrix  F_s-i  using an orthogonal matrix modifying
-C        the corresponding submatrix  R.  Simultaneously, apply the
-C        transformation to the corresponding block-rows of the matrices
-C        R  and  F.
-C
-         CALL DLACPY( 'Upper', L, LNOBR-L*I, R(L*(I-1)+1,L*(I-1)+1),
-     $                LDR, R(L*I+1,L*I+1), LDR )
-         CALL MB04OD( 'Full', L, LNOBR-L*(I+1), NROWML, R(L*I+1,L*I+1),
-     $                LDR, UL(1,L*(I-1)+1), LDUL, R(L*I+1,L*(I+1)+1),
-     $                LDR, UL(1,L*I+1), LDUL, DWORK(ITAU), DWORK(JWORK)
-     $              )
-C
-C        Apply the transformation to the corresponding block-rows of
-C        the matrix  G  and copy  H_(i+1)  in  H(L*i+1:L*(i+1),1:m).
-C
-         DO 80 J = 1, L
-            CALL MB04OY( NROWML, M*(NOBR-I), UL(1,L*(I-1)+J), DWORK(J),
-     $                   K(J,M*I+1), LDK, K(LP1,1), LDK, DWORK(JWORK) )
-   80    CONTINUE
-C
-         CALL DLACPY( 'Full', L, M, K(1,M*I+1), LDK, H(L*I+1,1), LDH )
-   90 CONTINUE
-C
-C     Return if only the factorization is needed.
-C
-      IF( M.EQ.0 .OR. .NOT.WITHB ) THEN
-         DWORK(1) = MAXWRK
-         RETURN
-      END IF
-C
-C     Set the precision parameters. A threshold value  EPS**(2/3)  is
-C     used for deciding to use pivoting or not, where  EPS  is the
-C     relative machine precision (see LAPACK Library routine DLAMCH).
-C
-      EPS    = DLAMCH( 'Precision' )
-      THRESH = EPS**( TWO/THREE )
-      TOLL   = TOL
-      IF( TOLL.LE.ZERO )
-     $   TOLL = LNOBR*LNOBR*EPS
-      SVLMAX = ZERO
-C
-C     Compute the reciprocal of the condition number of the triangular
-C     factor  R  of  Q.
-C     Workspace: need 3*L*NOBR.
-C
-      CALL DTRCON( '1-norm', 'Upper', 'NonUnit', LNOBR, R, LDR, RCOND,
-     $             DWORK, IWORK, IERR )
-C
-      IF ( RCOND.GT.MAX( TOLL, THRESH ) ) THEN
-C
-C        The triangular factor  R  is considered to be of full rank.
-C        Solve for  X,  R*X = H.
-C
-         CALL DTRSM( 'Left', 'Upper', 'NoTranspose', 'Non-unit',
-     $               LNOBR, M, ONE, R, LDR, H, LDH )
-      ELSE
-C
-C        Rank-deficient triangular factor  R.  Compute the
-C        minimum-norm least squares solution of  R*X = H  using
-C        the complete orthogonal factorization of  R.
-C
-         DO 100 I = 1, LNOBR
-            IWORK(I) = 0
-  100    CONTINUE
-C
-C        Workspace: need   4*L*NOBR+1;
-C                   prefer 3*L*NOBR+(L*NOBR+1)*NB.
-C
-         JWORK = ITAU + LNOBR
-         CALL DLASET( 'Lower', LNOBR-1, LNOBR, ZERO, ZERO, R(2,1), LDR )
-         CALL MB03OD( 'QR', LNOBR, LNOBR, R, LDR, IWORK, TOLL, SVLMAX,
-     $                DWORK(ITAU), RANK, SVAL, DWORK(JWORK),
-     $                LDWORK-JWORK+1, IERR )
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C        Workspace: need L*NOBR+M; prefer L*NOBR+M*NB.
-C
-         CALL DORMQR( 'Left', 'Transpose', LNOBR, M, LNOBR, R, LDR,
-     $                DWORK(ITAU), H, LDH, DWORK(JWORK), LDWORK-JWORK+1,
-     $                IERR )
-         IF ( RANK.LT.LNOBR ) THEN
-C
-C           The least squares problem is rank-deficient.
-C
-            IWARN = 4
-         END IF
-C
-C        Workspace: need L*NOBR+max(L*NOBR,M); prefer larger.
-C
-         CALL MB02QY( LNOBR, LNOBR, M, RANK, R, LDR, IWORK, H, LDH,
-     $                DWORK(ITAU), DWORK(JWORK), LDWORK-JWORK+1, IERR )
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) + JWORK - 1 )
-      END IF
-C
-C     Construct the matrix  D,  if needed.
-C
-      IF ( WITHD )
-     $   CALL DLACPY( 'Full', L, M, H(LDUN2+1,1), LDH, D, LDD )
-C
-C     Compute  B  by solving another linear system (possibly in
-C     a least squares sense).
-C
-C     Make a block-permutation of the rows of the right-hand side,  H,
-C     to construct the matrix
-C
-C        [ H(L*(s-2)+1:L*(s-1),:); ... H(L+1:L*2,:); H(1:L),:) ]
-C
-C     in  H(1:L*s-L,1:n).
-C
-      NOBRH = NOBR/2 + MOD( NOBR, 2 ) - 1
-C
-      DO 120 J = 1, M
-C
-         DO 110 I = 1, NOBRH
-            CALL DSWAP( L, H(L*(I-1)+1,J), 1, H(L*(NOBR-I-1)+1,J), 1 )
-  110    CONTINUE
-C
-  120 CONTINUE
-C
-C     Solve for  B  the matrix equation  GaL*B = H(1:L*s-L,:),  using
-C     the available QR factorization of  GaL,  if  METH = 'M'  and
-C     rank(GaL) = n, or the available pseudoinverse of  GaL,  otherwise.
-C
-      IF ( MOESP .AND. RANKR1.EQ.N ) THEN
-C
-C        The triangular factor  r1  of  GaL  is considered to be of
-C        full rank. Compute  Q1'*H  in  H  and then solve for  B,
-C        r1*B = H(1:n,:)  in  B,  where  Q1  is the orthogonal matrix
-C        in the QR factorization of  GaL.
-C        Workspace: need M; prefer M*NB.
-C
-         CALL DORMQR( 'Left', 'Transpose', LDUN2, M, N, R1, LDR1,
-     $                TAU1, H, LDH, DWORK, LDWORK, IERR )
-         MAXWRK = MAX( MAXWRK, INT( DWORK(1) ) )
-C
-C        Compute the solution in  B.
-C
-         CALL DLACPY( 'Full', N, M, H, LDH, B, LDB )
-C
-         CALL DTRTRS( 'Upper', 'NoTranspose', 'NonUnit', N, M, R1, LDR1,
-     $                B, LDB, IERR )
-         IF ( IERR.GT.0 ) THEN
-            INFO = 3
-            RETURN
-         END IF
-      ELSE
-C
-C        Rank-deficient triangular factor  r1.  Use the available
-C        pseudoinverse of  GaL  for computing  B  from  GaL*B = H.
-C
-         CALL DGEMM ( 'NoTranspose', 'NoTranspose', N, M, LDUN2, ONE,
-     $                PGAL, LDPGAL, H, LDH, ZERO, B, LDB )
-      END IF
-C
-C     Return optimal workspace in  DWORK(1)  and reciprocal condition
-C     number in  DWORK(2).
-C
-      DWORK(1) = MAXWRK
-      DWORK(2) = RCOND
-C
-      RETURN
-C
-C *** Last line of IB01PY ***
-      END
--- a/extra/control-devel/src/IB01QD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1081 +0,0 @@
-      SUBROUTINE IB01QD( JOBX0, JOB, N, M, L, NSMP, A, LDA, C, LDC, U,
-     $                   LDU, Y, LDY, X0, B, LDB, D, LDD, TOL, IWORK,
-     $                   DWORK, LDWORK, IWARN, 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 estimate the initial state and the system matrices  B  and  D
-C     of a linear time-invariant (LTI) discrete-time system, given the
-C     matrix pair  (A,C)  and the input and output trajectories of the
-C     system. The model structure is :
-C
-C           x(k+1) = Ax(k) + Bu(k),   k >= 0,
-C           y(k)   = Cx(k) + Du(k),
-C
-C     where  x(k)  is the  n-dimensional state vector (at time k),
-C            u(k)  is the  m-dimensional input vector,
-C            y(k)  is the  l-dimensional output vector,
-C     and  A, B, C, and D  are real matrices of appropriate dimensions.
-C     Matrix  A  is assumed to be in a real Schur form.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBX0   CHARACTER*1
-C             Specifies whether or not the initial state should be
-C             computed, as follows:
-C             = 'X':  compute the initial state x(0);
-C             = 'N':  do not compute the initial state (x(0) is known
-C                     to be zero).
-C
-C     JOB     CHARACTER*1
-C             Specifies which matrices should be computed, as follows:
-C             = 'B':  compute the matrix B only (D is known to be zero);
-C             = 'D':  compute the matrices B and D.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the system.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     NSMP    (input) INTEGER
-C             The number of rows of matrices  U  and  Y  (number of
-C             samples,  t).
-C             NSMP >= N*M + a + e,  where
-C             a = 0,  if  JOBX0 = 'N';
-C             a = N,  if  JOBX0 = 'X';
-C             e = 0,  if  JOBX0 = 'X'  and  JOB = 'B';
-C             e = 1,  if  JOBX0 = 'N'  and  JOB = 'B';
-C             e = M,  if  JOB   = 'D'.
-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  in a real Schur form.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= MAX(1,N).
-C
-C     C       (input) DOUBLE PRECISION array, dimension (LDC,N)
-C             The leading L-by-N part of this array must contain the
-C             system output matrix  C  (corresponding to the real Schur
-C             form of  A).
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.  LDC >= L.
-C
-C     U       (input/output) DOUBLE PRECISION array, dimension (LDU,M)
-C             On entry, the leading NSMP-by-M part of this array must
-C             contain the t-by-m input-data sequence matrix  U,
-C             U = [u_1 u_2 ... u_m].  Column  j  of  U  contains the
-C             NSMP  values of the j-th input component for consecutive
-C             time increments.
-C             On exit, if  JOB = 'D',  the leading NSMP-by-M part of
-C             this array contains details of the QR factorization of
-C             the t-by-m matrix  U, possibly computed sequentially
-C             (see METHOD).
-C             If  JOB = 'B',  this array is unchanged on exit.
-C             If M = 0, this array is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of the array U.
-C             LDU >= MAX(1,NSMP),  if M > 0;
-C             LDU >= 1,            if M = 0.
-C
-C     Y       (input) DOUBLE PRECISION array, dimension (LDY,L)
-C             The leading NSMP-by-L part of this array must contain the
-C             t-by-l output-data sequence matrix  Y,
-C             Y = [y_1 y_2 ... y_l].  Column  j  of  Y  contains the
-C             NSMP  values of the j-th output component for consecutive
-C             time increments.
-C
-C     LDY     INTEGER
-C             The leading dimension of the array Y.  LDY >= MAX(1,NSMP).
-C
-C     X0      (output) DOUBLE PRECISION array, dimension (N)
-C             If  JOBX0 = 'X',  the estimated initial state of the
-C             system,  x(0).
-C             If  JOBX0 = 'N',  x(0)  is set to zero without any
-C             calculations.
-C
-C     B       (output) DOUBLE PRECISION array, dimension (LDB,M)
-C             If  N > 0,  M > 0,  and  INFO = 0,  the leading N-by-M
-C             part of this array contains the system input matrix  B
-C             in the coordinates corresponding to the real Schur form
-C             of  A.
-C             If  N = 0  or  M = 0,  this array is not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.
-C             LDB >= N,  if  N > 0  and  M > 0;
-C             LDB >= 1,  if  N = 0  or   M = 0.
-C
-C     D       (output) DOUBLE PRECISION array, dimension (LDD,M)
-C             If  M > 0,  JOB = 'D',  and  INFO = 0,  the leading
-C             L-by-M part of this array contains the system input-output
-C             matrix  D.
-C             If  M = 0  or  JOB = 'B',  this array is not referenced.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.
-C             LDD >= L,  if  M > 0  and  JOB = 'D';
-C             LDD >= 1,  if  M = 0  or   JOB = 'B'.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used for estimating the rank of
-C             matrices. If the user sets  TOL > 0,  then the given value
-C             of  TOL  is used as a lower bound for the reciprocal
-C             condition number;  a matrix whose estimated condition
-C             number is less than  1/TOL  is considered to be of full
-C             rank.  If the user sets  TOL <= 0,  then  EPS  is used
-C             instead, where  EPS  is the relative machine precision
-C             (see LAPACK Library routine DLAMCH).  TOL <= 1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK), where
-C             LIWORK >= N*M + a,            if  JOB = 'B',
-C             LIWORK >= max( N*M + a, M ),  if  JOB = 'D',
-C             with  a = 0,  if  JOBX0 = 'N';
-C                   a = N,  if  JOBX0 = 'X'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of LDWORK;  DWORK(2)  contains the reciprocal condition
-C             number of the triangular factor of the QR factorization of
-C             the matrix  W2  (see METHOD); if  M > 0  and  JOB = 'D',
-C             DWORK(3)  contains the reciprocal condition number of the
-C             triangular factor of the QR factorization of  U.
-C             On exit, if  INFO = -23,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= max( LDW1, min( LDW2, LDW3 ) ),  where
-C             LDW1 = 2,          if  M = 0  or   JOB = 'B',
-C             LDW1 = 3,          if  M > 0  and  JOB = 'D',
-C             LDWa = t*L*(r + 1) + max( N + max( d, f ), 6*r ),
-C             LDW2 = LDWa,       if  M = 0  or  JOB = 'B',
-C             LDW2 = max( LDWa, t*L*(r + 1) + 2*M*M + 6*M ),
-C                                if  M > 0  and JOB = 'D',
-C             LDWb = (b + r)*(r + 1) +
-C                     max( q*(r + 1) + N*N*M + c + max( d, f ), 6*r ),
-C             LDW3 = LDWb,       if  M = 0  or  JOB = 'B',
-C             LDW3 = max( LDWb, (b + r)*(r + 1) + 2*M*M + 6*M ),
-C                                if  M > 0  and JOB = 'D',
-C                r = N*M + a,
-C                a = 0,                  if  JOBX0 = 'N',
-C                a = N,                  if  JOBX0 = 'X';
-C                b = 0,                  if  JOB   = 'B',
-C                b = L*M,                if  JOB   = 'D';
-C                c = 0,                  if  JOBX0 = 'N',
-C                c = L*N,                if  JOBX0 = 'X';
-C                d = 0,                  if  JOBX0 = 'N',
-C                d = 2*N*N + N,          if  JOBX0 = 'X';
-C                f = 2*r,                if  JOB   = 'B'   or  M = 0,
-C                f = M + max( 2*r, M ),  if  JOB   = 'D'  and  M > 0;
-C                q = b + r*L.
-C             For good performance,  LDWORK  should be larger.
-C             If  LDWORK >= LDW2  or
-C                 LDWORK >= t*L*(r + 1) + (b + r)*(r + 1) + N*N*M + c +
-C                           max( d, f ),
-C             then standard QR factorizations of the matrices  U  and/or
-C             W2  (see METHOD) are used.
-C             Otherwise, the QR factorizations are computed sequentially
-C             by performing  NCYCLE  cycles, each cycle (except possibly
-C             the last one) processing  s < t  samples, where  s  is
-C             chosen from the equation
-C               LDWORK = s*L*(r + 1) + (b + r)*(r + 1) + N*N*M + c +
-C                        max( d, f ).
-C             (s  is at least  N*M+a+e,  the minimum value of  NSMP.)
-C             The computational effort may increase and the accuracy may
-C             decrease with the decrease of  s.  Recommended value is
-C             LDWORK = LDW2,  assuming a large enough cache size, to
-C             also accommodate  A,  C,  U,  and  Y.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 4:  the least squares problem to be solved has a
-C                   rank-deficient coefficient matrix.
-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             = 2:  the singular value decomposition (SVD) algorithm did
-C                   not converge.
-C
-C     METHOD
-C
-C     An extension and refinement of the method in [1,2] is used.
-C     Specifically, denoting
-C
-C           X = [ vec(D')' vec(B)' x0' ]',
-C
-C     where  vec(M)  is the vector obtained by stacking the columns of
-C     the matrix  M,  then  X  is the least squares solution of the
-C     system  S*X = vec(Y),  with the matrix  S = [ diag(U)  W ],
-C     defined by
-C
-C           ( U         |     | ... |     |     | ... |     |         )
-C           (   U       |  11 | ... |  n1 |  12 | ... |  nm |         )
-C       S = (     :     | y   | ... | y   | y   | ... | y   | P*Gamma ),
-C           (       :   |     | ... |     |     | ... |     |         )
-C           (         U |     | ... |     |     | ... |     |         )
-C                                                                     ij
-C     diag(U)  having  L  block rows and columns.  In this formula,  y
-C     are the outputs of the system for zero initial state computed
-C     using the following model, for j = 1:m, and for i = 1:n,
-C            ij          ij                    ij
-C           x  (k+1) = Ax  (k) + e_i u_j(k),  x  (0) = 0,
-C
-C            ij          ij
-C           y  (k)   = Cx  (k),
-C
-C     where  e_i  is the i-th n-dimensional unit vector,  Gamma  is
-C     given by
-C
-C                (     C     )
-C                (    C*A    )
-C        Gamma = (   C*A^2   ),
-C                (     :     )
-C                ( C*A^(t-1) )
-C
-C     and  P  is a permutation matrix that groups together the rows of
-C     Gamma  depending on the same row of  C,  namely
-C     [ c_j;  c_j*A;  c_j*A^2; ...  c_j*A^(t-1) ],  for j = 1:L.
-C     The first block column,  diag(U),  is not explicitly constructed,
-C     but its structure is exploited. The last block column is evaluated
-C     using powers of A with exponents 2^k. No interchanges are applied.
-C     A special QR decomposition of the matrix  S  is computed. Let
-C     U = q*[ r' 0 ]'  be the QR decomposition of  U,  if  M > 0,  where
-C     r  is  M-by-M.   Then,  diag(q')  is applied to  W  and  vec(Y).
-C     The block-rows of  S  and  vec(Y)  are implicitly permuted so that
-C     matrix  S  becomes
-C
-C        ( diag(r)  W1 )
-C        (    0     W2 ),
-C
-C     where  W1  has L*M rows. Then, the QR decomposition of  W2 is
-C     computed (sequentially, if  M > 0) and used to obtain  B  and  x0.
-C     The intermediate results and the QR decomposition of  U  are
-C     needed to find  D.  If a triangular factor is too ill conditioned,
-C     then singular value decomposition (SVD) is employed. SVD is not
-C     generally needed if the input sequence is sufficiently
-C     persistently exciting and  NSMP  is large enough.
-C     If the matrix  W  cannot be stored in the workspace (i.e.,
-C     LDWORK < LDW2),  the QR decompositions of  W2  and  U  are
-C     computed sequentially.
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Varga, A.
-C         Some Experience with the MOESP Class of Subspace Model
-C         Identification Methods in Identifying the BO105 Helicopter.
-C         Report TR R165-94, DLR Oberpfaffenhofen, 1994.
-C
-C     [2] Sima, V., and Varga, A.
-C         RASP-IDENT : Subspace Model Identification Programs.
-C         Deutsche Forschungsanstalt fur Luft- und Raumfahrt e. V.,
-C         Report TR R888-94, DLR Oberpfaffenhofen, Oct. 1994.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is numerically stable.
-C
-C     FURTHER COMMENTS
-C
-C     The algorithm for computing the system matrices  B  and  D  is
-C     less efficient than the MOESP or N4SID algorithms implemented in
-C     SLICOT Library routine IB01PD, because a large least squares
-C     problem has to be solved, but the accuracy is better, as the
-C     computed matrices  B  and  D  are fitted to the input and output
-C     trajectories. However, if matrix  A  is unstable, the computed
-C     matrices  B  and  D  could be inaccurate.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 2000.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Identification methods; least squares solutions; multivariable
-C     systems; QR decomposition; singular value decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, THREE
-      PARAMETER          ( ZERO  = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
-     $                     THREE = 3.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   TOL
-      INTEGER            INFO, IWARN, L, LDA, LDB, LDC, LDD, LDU,
-     $                   LDWORK, LDY, M, N, NSMP
-      CHARACTER          JOB, JOBX0
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA, *), B(LDB, *), C(LDC, *), D(LDD, *),
-     $                   DWORK(*),  U(LDU, *), X0(*), Y(LDY, *)
-      INTEGER            IWORK(*)
-C     .. Local Scalars ..
-      DOUBLE PRECISION   RCOND, RCONDU, TOLL
-      INTEGER            I, I2, IA, IAS, IC, ICYCLE, IE, IERR, IEXPON,
-     $                   IG, IGAM, IGS, INI, INIH, INIR, INIS, INY,
-     $                   INYGAM, IQ, IREM, IRHS, ISIZE, ISV, ITAU,
-     $                   ITAUU, IUPNT, IX, IXINIT, IXSAVE, IY, IYPNT, J,
-     $                   JWORK, K, LDDW, LDR, LDW2, LDW3, LM, LN, LNOB,
-     $                   MAXWRK, MINSMP, MINWLS, MINWRK, N2M, NCOL,
-     $                   NCP1, NCYCLE, NM, NN, NOBS, NROW, NSMPL, RANK
-      LOGICAL            FIRST, NCYC, POWER2, WITHB, WITHD, WITHX0
-C     .. Local Arrays ..
-      DOUBLE PRECISION   DUM(1)
-C     .. External Functions ..
-      LOGICAL            LSAME
-      INTEGER            ILAENV
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           DLAMCH, ILAENV, LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DAXPY, DCOPY, DGELSS, DGEMV, DGEQRF, DLACPY,
-     $                   DLASET, DORMQR, DTRCON, DTRMM, DTRMV, DTRSM,
-     $                   MA02AD, MB01TD, MB02UD, MB04OD, MB04OY, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          DBLE, INT, LOG, MAX, MIN, MOD
-C     .. Executable Statements ..
-C
-C     Check the input parameters.
-C
-      WITHD  = LSAME( JOB,   'D' )
-      WITHB  = LSAME( JOB,   'B' ) .OR. WITHD
-      WITHX0 = LSAME( JOBX0, 'X' )
-C
-      IWARN = 0
-      INFO  = 0
-      LM    = L*M
-      LN    = L*N
-      NN    = N*N
-      NM    = N*M
-      N2M   = N*NM
-      NCOL  = NM
-      IF( WITHX0 )
-     $   NCOL = NCOL + N
-      MINSMP  = NCOL
-      IF( WITHD ) THEN
-         MINSMP = MINSMP + M
-         IQ     = MINSMP
-      ELSE IF ( .NOT.WITHX0 ) THEN
-         IQ     = MINSMP
-         MINSMP = MINSMP + 1
-      ELSE
-         IQ     = MINSMP
-      END IF
-C
-      IF( .NOT.( WITHX0 .OR. LSAME( JOBX0, 'N' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.WITHB ) THEN
-         INFO = -2
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( L.LE.0 ) THEN
-         INFO = -5
-      ELSE IF( NSMP.LT.MINSMP ) THEN
-         INFO = -6
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( LDC.LT.L ) THEN
-         INFO = -10
-      ELSE IF( LDU.LT.1 .OR. ( M.GT.0 .AND. LDU.LT.NSMP ) ) THEN
-         INFO = -12
-      ELSE IF( LDY.LT.MAX( 1, NSMP ) ) THEN
-         INFO = -14
-      ELSE IF( LDB.LT.1 .OR. ( LDB.LT.N .AND. M.GT.0 ) )
-     $      THEN
-         INFO = -17
-      ELSE IF( LDD.LT.1 .OR. ( WITHD .AND. LDD.LT.L .AND. M.GT.0 ) )
-     $      THEN
-         INFO = -19
-      ELSE IF( TOL.GT.ONE ) THEN
-         INFO = -20
-      END IF
-C
-C     Compute workspace.
-C      (Note: Comments in the code beginning "Workspace:" describe the
-C       minimal amount of workspace needed at that point in the code,
-C       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
-      NSMPL = NSMP*L
-      IQ    = IQ*L
-      NCP1  = NCOL + 1
-      ISIZE = NSMPL*NCP1
-      IF ( N.GT.0 .AND. WITHX0 ) THEN
-         IC = 2*NN + N
-      ELSE
-         IC = 0
-      END IF
-      MINWLS = NCOL*NCP1
-      IF ( WITHD )
-     $   MINWLS = MINWLS + LM*NCP1
-      IF ( M.GT.0 .AND. WITHD ) THEN
-         IA = M + MAX( 2*NCOL, M )
-      ELSE
-         IA = 2*NCOL
-      END IF
-      ITAU = N2M + MAX( IC, IA )
-      IF ( WITHX0 )
-     $   ITAU = ITAU + LN
-      LDW2 = ISIZE  + MAX( N + MAX( IC, IA ), 6*NCOL )
-      LDW3 = MINWLS + MAX( IQ*NCP1 + ITAU, 6*NCOL )
-      IF ( M.GT.0 .AND. WITHD ) THEN
-         LDW2 = MAX( LDW2, ISIZE  + 2*M*M + 6*M )
-         LDW3 = MAX( LDW3, MINWLS + 2*M*M + 6*M )
-      END IF
-      MINWRK = MIN( LDW2, LDW3 )
-      MINWRK = MAX( MINWRK, 2 )
-      IF ( M.GT.0 .AND. WITHD )
-     $   MINWRK = MAX( MINWRK, 3 )
-      IF ( INFO.EQ.0 .AND. LDWORK.GE.MINWRK ) THEN
-         IF ( M.GT.0 .AND. WITHD ) THEN
-            MAXWRK = ISIZE + N + M +
-     $               MAX( M*ILAENV( 1, 'DGEQRF', ' ', NSMP, M, -1, -1 ),
-     $                    NCOL + NCOL*ILAENV( 1, 'DGEQRF', ' ', NSMP-M,
-     $                                        NCOL, -1, -1 ) )
-            MAXWRK = MAX( MAXWRK, ISIZE + N + M +
-     $                    MAX( NCP1*ILAENV( 1, 'DORMQR', 'LT', NSMP,
-     $                                      NCP1, M, -1 ),
-     $                         NCOL + ILAENV( 1, 'DORMQR', 'LT',
-     $                                        NSMP-M, 1, NCOL, -1 ) ) )
-         ELSE
-            MAXWRK = ISIZE + N + NCOL +
-     $               MAX( NCOL*ILAENV( 1, 'DGEQRF', ' ', NSMPL, NCOL,
-     $                                 -1, -1 ),
-     $                         ILAENV( 1, 'DORMQR', 'LT',NSMPL, 1, NCOL,
-     $                                 -1 ) )
-         END IF
-         MAXWRK = MAX( MAXWRK, MINWRK )
-      END IF
-C
-      IF ( INFO.EQ.0 .AND. LDWORK.LT.MINWRK ) THEN
-         INFO = -23
-         DWORK(1) = MINWRK
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01QD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( MAX( N, M ).EQ.0 ) THEN
-         DWORK(2) = ONE
-         IF ( M.GT.0 .AND. WITHD ) THEN
-            DWORK(1) = THREE
-            DWORK(3) = ONE
-         ELSE
-            DWORK(1) = TWO
-         END IF
-         RETURN
-      END IF
-C
-C     Set up the least squares problem, either directly, if enough
-C     workspace, or sequentially, otherwise.
-C
-      IYPNT = 1
-      IUPNT = 1
-      LDDW  = ( LDWORK - MINWLS - ITAU )/NCP1
-      NOBS  = MIN( NSMP, LDDW/L )
-C
-      IF ( LDWORK.GE.LDW2 .OR. NSMP.LE.NOBS ) THEN
-C
-C        Enough workspace for solving the problem directly.
-C
-         NCYCLE = 1
-         NOBS   = NSMP
-         LDDW   = MAX( 1, NSMPL )
-         IF ( WITHD ) THEN
-            INIR = M + 1
-         ELSE
-            INIR = 1
-         END IF
-         INY  = 1
-         INIS = 1
-      ELSE
-C
-C        NCYCLE > 1  cycles are needed for solving the problem
-C        sequentially, taking  NOBS  samples in each cycle (or the
-C        remaining samples in the last cycle).
-C
-         LNOB   = L*NOBS
-         LDDW   = MAX( 1, LNOB )
-         NCYCLE = NSMP/NOBS
-         IF ( MOD( NSMP, NOBS ).NE.0 )
-     $      NCYCLE = NCYCLE + 1
-         INIR = 1
-         INIH = INIR + NCOL*NCOL
-         INIS = INIH + NCOL
-         IF ( WITHD ) THEN
-            INY = INIS + LM*NCP1
-         ELSE
-            INY = INIS
-         END IF
-      END IF
-C
-      NCYC   = NCYCLE.GT.1
-      INYGAM = INY  + LDDW*NM
-      IRHS   = INY  + LDDW*NCOL
-      IXINIT = IRHS + LDDW
-      IF( NCYC ) THEN
-         IC = IXINIT + N2M
-         IF ( WITHX0 ) THEN
-            IA = IC + LN
-         ELSE
-            IA = IC
-         END IF
-         LDR = MAX( 1, NCOL )
-         IE  = INY
-      ELSE
-         IF ( WITHD ) THEN
-            INIH = IRHS + M
-         ELSE
-            INIH = IRHS
-         END IF
-         IA  = IXINIT + N
-         LDR = LDDW
-         IE  = IXINIT
-      END IF
-      IF ( N.GT.0 .AND. WITHX0 )
-     $   IAS = IA + NN
-C
-      ITAUU = IA
-      IF ( WITHD ) THEN
-         ITAU = ITAUU + M
-      ELSE
-         ITAU = ITAUU
-      END IF
-      DUM(1) = ZERO
-C
-      DO 190 ICYCLE = 1, NCYCLE
-         FIRST = ICYCLE.EQ.1
-         IF ( .NOT.FIRST ) THEN
-            IF ( ICYCLE.EQ.NCYCLE ) THEN
-               NOBS = NSMP - ( NCYCLE - 1 )*NOBS
-               LNOB = L*NOBS
-            END IF
-         END IF
-C
-         IY     = INY
-         IXSAVE = IXINIT
-C
-C        Compute the  M*N  output trajectories for zero initial state
-C        or for the saved final state value of the previous cycle.
-C        This can be performed in parallel.
-C        Workspace: need  s*L*(r + 1) + b + w,
-C                   where r = M*N + a,  s = NOBS,
-C                         a = 0,             if JOBX0 = 'N';
-C                         a = N,             if JOBX0 = 'X';
-C                         b = N,             if NCYCLE = 1;
-C                         b = N*N*M,         if NCYCLE > 1;
-C                         w = 0,             if NCYCLE = 1;
-C                         w = r*(r+1),       if NCYCLE > 1,  JOB = 'B';
-C                         w = (M*L+r)*(r+1), if NCYCLE > 1,  JOB = 'D'.
-C
-         DO 40 J = 1, M
-            DO 30 I = 1, N
-C                            ij
-C              Compute the  y    trajectory and put the vectorized form
-C              of it in an appropriate column of  DWORK.  To gain in
-C              efficiency, a specialization of SLICOT Library routine
-C              TF01ND is used.
-C
-               IF ( FIRST )
-     $            CALL DCOPY( N, DUM, 0, DWORK(IXSAVE), 1 )
-               CALL DCOPY( N, DWORK(IXSAVE), 1, X0, 1 )
-               INI = IY
-C
-               DO 20 K = 1, NOBS
-                  CALL DGEMV( 'No transpose', L, N, ONE, C, LDC, X0, 1,
-     $                        ZERO, DWORK(IY), NOBS )
-                  IY = IY + 1
-                  CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', N,
-     $                        A, LDA, X0, 1 )
-C
-                  DO 10 IX = 2, N
-                     X0(IX) = X0(IX) + A(IX,IX-1)*DWORK(IXSAVE+IX-2)
-   10             CONTINUE
-C
-                  X0(I) = X0(I) + U(IUPNT+K-1,J)
-                  CALL DCOPY( N, X0, 1, DWORK(IXSAVE), 1 )
-   20          CONTINUE
-C
-               IF ( NCYC )
-     $            IXSAVE = IXSAVE + N
-               IY = INI + LDDW
-   30       CONTINUE
-C
-   40    CONTINUE
-C
-         IF ( N.GT.0 .AND. WITHX0 ) THEN
-C
-C           Compute the permuted extended observability matrix  Gamma
-C                                                                ij
-C           in the following  N  columns of  DWORK  (after the  y
-C           trajectories).  Gamma  is directly constructed in the
-C           required row structure.
-C           Workspace: need  s*L*(r + 1) + 2*N*N + N + b + c + w,
-C                      where c = 0,   if NCYCLE = 1;
-C                            c = L*N, if NCYCLE > 1.
-C
-            JWORK  = IAS + NN
-            IG     = INYGAM
-            IEXPON = INT( LOG( DBLE( NOBS ) )/LOG( TWO ) )
-            IREM   = NOBS - 2**IEXPON
-            POWER2 = IREM.EQ.0
-            IF ( .NOT.POWER2 )
-     $         IEXPON = IEXPON + 1
-C
-            IF ( FIRST ) THEN
-C
-               DO 50 I = 1, N
-                  CALL DCOPY( L, C(1,I), 1, DWORK(IG), NOBS )
-                  IG = IG + LDDW
-   50          CONTINUE
-C
-            ELSE
-C
-               DO 60 I = IC, IC + LN - 1, L
-                  CALL DCOPY( L, DWORK(I), 1, DWORK(IG), NOBS )
-                  IG = IG + LDDW
-   60          CONTINUE
-C
-            END IF
-C                                          p
-C           Use powers of the matrix  A:  A ,  p = 2**(J-1).
-C
-            CALL DLACPY( 'Upper', N, N, A, LDA, DWORK(IA), N )
-            IF( N.GT.1 )
-     $         CALL DCOPY( N-1, A(2,1), LDA+1, DWORK(IA+1), N+1 )
-            I2   = 1
-            NROW = 0
-C
-            DO 90 J = 1, IEXPON
-               IGAM = INYGAM
-               IF ( J.LT.IEXPON .OR. POWER2 ) THEN
-                  NROW = I2
-               ELSE
-                  NROW = IREM
-               END IF
-C
-               DO 80 I = 1, L
-                  CALL DLACPY( 'Full', NROW, N, DWORK(IGAM), LDDW,
-     $                         DWORK(IGAM+I2), LDDW )
-                  CALL DTRMM(  'Right', 'Upper', 'No Transpose',
-     $                         'Non Unit', NROW, N, ONE, DWORK(IA), N,
-     $                         DWORK(IGAM+I2), LDDW )
-                  IG = IGAM
-C                                                                  p
-C                 Compute the contribution of the subdiagonal of  A
-C                 to the product.
-C
-                  DO 70 IX = 1, N - 1
-                     CALL DAXPY( NROW, DWORK(IA+(IX-1)*N+IX),
-     $                           DWORK(IG+LDDW), 1, DWORK(IG+I2), 1 )
-                     IG = IG + LDDW
-   70             CONTINUE
-C
-                  IGAM = IGAM + NOBS
-   80          CONTINUE
-C
-               IF ( J.LT.IEXPON ) THEN
-                  CALL DLACPY( 'Upper', N, N, DWORK(IA), N, DWORK(IAS),
-     $                         N )
-                  IF( N.GT.1 )
-     $               CALL DCOPY( N-1, DWORK(IA+1), N+1, DWORK(IAS+1),
-     $                           N+1 )
-                  CALL MB01TD( N, DWORK(IAS), N, DWORK(IA), N,
-     $                         DWORK(JWORK), IERR )
-                  I2 = I2*2
-               END IF
-   90       CONTINUE
-C
-            IF ( NCYC .AND. ICYCLE.LT.NCYCLE ) THEN
-               IG  = INYGAM + I2 + NROW - 1
-               IGS = IG
-C
-               DO 100 I = IC, IC + LN - 1, L
-                  CALL DCOPY( L, DWORK(IG), NOBS, DWORK(I), 1 )
-                  IG = IG + LDDW
-  100          CONTINUE
-C
-               CALL DTRMM( 'Right', 'Upper', 'No Transpose', 'Non Unit',
-     $                     L, N, ONE, A, LDA, DWORK(IC), L )
-               IG = IGS
-C
-C              Compute the contribution of the subdiagonal of  A  to the
-C              product.
-C
-               DO 110 IX = 1, N - 1
-                  CALL DAXPY( L, A(IX+1,IX), DWORK(IG+LDDW), NOBS,
-     $                        DWORK(IC+(IX-1)*L), 1 )
-                  IG = IG + LDDW
-  110          CONTINUE
-C
-            END IF
-         END IF
-C
-C        Setup (part of) the right hand side of the least squares
-C        problem.
-C
-         IY = IRHS
-C
-         DO 120 K = 1, L
-            CALL DCOPY( NOBS, Y(IYPNT,K), 1, DWORK(IY), 1 )
-            IY = IY + NOBS
-  120    CONTINUE
-C
-C        Compress the data using a special QR factorization.
-C        Workspace: need   v + y,
-C                   where  v = s*L*(r + 1) + b + c + w + x,
-C                          x = M,  y = max( 2*r, M ),
-C                                             if  JOB = 'D'  and  M > 0,
-C                          x = 0,  y = 2*r,   if  JOB = 'B'  or   M = 0.
-C
-         IF ( M.GT.0 .AND. WITHD ) THEN
-C
-C           Case 1:  D  is requested.
-C
-            JWORK = ITAU
-            IF ( FIRST ) THEN
-               INI = INY + M
-C
-C              Compress the first or single segment of  U,  U1 = Q1*R1.
-C              Workspace: need   v + M;
-C                         prefer v + M*NB.
-C
-               CALL DGEQRF( NOBS, M, U, LDU, DWORK(ITAUU), DWORK(JWORK),
-     $                      LDWORK-JWORK+1, IERR )
-C                                                  ij
-C              Apply  diag(Q1')  to the matrix  [ y   Gamma Y ].
-C              Workspace: need   v + r + 1,
-C                         prefer v + (r + 1)*NB.
-C
-               DO 130 K = 1, L
-                  CALL DORMQR( 'Left', 'Transpose', NOBS, NCP1, M, U,
-     $                         LDU, DWORK(ITAUU), DWORK(INY+(K-1)*NOBS),
-     $                         LDDW, DWORK(JWORK), LDWORK-JWORK+1,
-     $                         IERR )
-  130          CONTINUE
-C
-               IF ( NCOL.GT.0 ) THEN
-C
-C                 Compress the first part of the first data segment of
-C                    ij
-C                 [ y   Gamma ].
-C                 Workspace: need   v + 2*r,
-C                            prefer v + r + r*NB.
-C
-                  JWORK = ITAU + NCOL
-                  CALL DGEQRF( NOBS-M, NCOL, DWORK(INI), LDDW,
-     $                         DWORK(ITAU), DWORK(JWORK),
-     $                         LDWORK-JWORK+1, IERR )
-C
-C                 Apply the transformation to the corresponding right
-C                 hand side part.
-C                 Workspace: need   v + r + 1,
-C                            prefer v + r + NB.
-C
-                  CALL DORMQR( 'Left', 'Transpose', NOBS-M, 1, NCOL,
-     $                         DWORK(INI), LDDW, DWORK(ITAU),
-     $                         DWORK(IRHS+M), LDDW, DWORK(JWORK),
-     $                         LDWORK-JWORK+1, IERR )
-C
-C                 Compress the remaining parts of the first data segment
-C                        ij
-C                 of  [ y   Gamma ].
-C                 Workspace: need   v + r - 1.
-C
-                  DO 140 K = 2, L
-                     CALL MB04OD( 'Full', NCOL, 1, NOBS-M, DWORK(INI),
-     $                            LDDW, DWORK(INI+(K-1)*NOBS), LDDW,
-     $                            DWORK(IRHS+M), LDDW,
-     $                            DWORK(IRHS+M+(K-1)*NOBS), LDDW,
-     $                            DWORK(ITAU), DWORK(JWORK) )
-  140             CONTINUE
-C
-               END IF
-C
-               IF ( NCYC ) THEN
-C                                                   ij
-C                 Save the triangular factor of  [ y   Gamma ],  the
-C                 corresponding right hand side, and the first  M  rows
-C                 in each  NOBS  group of rows.
-C                 Workspace: need   v.
-C
-                  CALL DLACPY( 'Upper', NCOL, NCP1, DWORK(INI), LDDW,
-     $                         DWORK(INIR), LDR )
-C
-                  DO 150 K = 1, L
-                     CALL DLACPY( 'Full', M, NCP1,
-     $                            DWORK(INY +(K-1)*NOBS), LDDW,
-     $                            DWORK(INIS+(K-1)*M), LM )
-  150             CONTINUE
-C
-               END IF
-            ELSE
-C
-C              Compress the current data segment of  U,  Ui = Qi*Ri,
-C              i = ICYCLE.
-C              Workspace: need   v + r + 1.
-C
-               CALL MB04OD( 'Full', M, NCP1, NOBS, U, LDU, U(IUPNT,1),
-     $                      LDU, DWORK(INIS), LM, DWORK(INY), LDDW,
-     $                      DWORK(ITAUU), DWORK(JWORK) )
-C
-C              Apply  diag(Qi')  to the appropriate part of the matrix
-C                 ij
-C              [ y   Gamma Y ].
-C              Workspace: need   v + r + 1.
-C
-               DO 170 K = 2, L
-C
-                  DO 160 IX = 1, M
-                     CALL MB04OY( NOBS, NCP1, U(IUPNT,IX),
-     $                            DWORK(ITAUU+IX-1),
-     $                            DWORK(INIS+(K-1)*M+IX-1), LM,
-     $                            DWORK(INY+(K-1)*NOBS), LDDW,
-     $                            DWORK(JWORK) )
-  160             CONTINUE
-C
-  170          CONTINUE
-C
-               IF ( NCOL.GT.0 ) THEN
-C
-                  JWORK = ITAU + NCOL
-C
-C                 Compress the current (but not the first) data segment
-C                        ij
-C                 of  [ y   Gamma ].
-C                 Workspace: need   v + r - 1.
-C
-                  DO 180 K = 1, L
-                     CALL MB04OD( 'Full', NCOL, 1, NOBS, DWORK(INIR),
-     $                            LDR, DWORK(INY+(K-1)*NOBS), LDDW,
-     $                            DWORK(INIH), LDR,
-     $                            DWORK(IRHS+(K-1)*NOBS), LDDW,
-     $                            DWORK(ITAU), DWORK(JWORK) )
-  180             CONTINUE
-C
-               END IF
-            END IF
-C
-         ELSE IF ( NCOL.GT.0 ) THEN
-C
-C           Case 2:  D  is known to be zero.
-C
-            JWORK = ITAU + NCOL
-            IF ( FIRST ) THEN
-C
-C              Compress the first or single data segment of
-C                 ij
-C              [ y   Gamma ].
-C              Workspace: need   v + 2*r,
-C                         prefer v + r + r*NB.
-C
-               CALL DGEQRF( LDDW, NCOL, DWORK(INY), LDDW, DWORK(ITAU),
-     $                      DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-C              Apply the transformation to the right hand side.
-C              Workspace: need   v + r + 1,
-C                         prefer v + r + NB.
-C
-               CALL DORMQR( 'Left', 'Transpose', LDDW, 1, NCOL,
-     $                      DWORK(INY), LDDW, DWORK(ITAU), DWORK(IRHS),
-     $                      LDDW, DWORK(JWORK), LDWORK-JWORK+1, IERR )
-               IF ( NCYC ) THEN
-C                                                   ij
-C                 Save the triangular factor of  [ y   Gamma ]  and the
-C                 corresponding right hand side.
-C                 Workspace: need   v.
-C
-                  CALL DLACPY( 'Upper', NCOL, NCP1, DWORK(INY), LDDW,
-     $                         DWORK(INIR), LDR )
-               END IF
-            ELSE
-C
-C              Compress the current (but not the first) data segment.
-C              Workspace: need   v + r - 1.
-C
-               CALL MB04OD( 'Full', NCOL, 1, LNOB, DWORK(INIR), LDR,
-     $                      DWORK(INY), LDDW, DWORK(INIH), LDR,
-     $                      DWORK(IRHS), LDDW, DWORK(ITAU),
-     $                      DWORK(JWORK) )
-            END IF
-         END IF
-C
-         IUPNT = IUPNT + NOBS
-         IYPNT = IYPNT + NOBS
-  190 CONTINUE
-C
-C     Estimate the reciprocal condition number of the triangular factor
-C     of the QR decomposition.
-C     Workspace: need  u + 3*r, where
-C                      u = t*L*(r + 1), if NCYCLE = 1;
-C                      u = w,           if NCYCLE > 1.
-C
-      CALL DTRCON( '1-norm', 'Upper', 'No Transpose', NCOL, DWORK(INIR),
-     $             LDR, RCOND, DWORK(IE), IWORK, IERR )
-C
-      TOLL = TOL
-      IF ( TOLL.LE.ZERO )
-     $   TOLL = DLAMCH( 'Precision' )
-      IF ( RCOND.LE.TOLL**( TWO/THREE ) ) THEN
-         IWARN = 4
-C
-C        The least squares problem is ill-conditioned.
-C        Use SVD to solve it.
-C        Workspace: need   u + 6*r;
-C                   prefer larger.
-C
-         IF ( NCOL.GT.1 )
-     $      CALL DLASET( 'Lower', NCOL-1, NCOL-1, ZERO, ZERO,
-     $                   DWORK(INIR+1), LDR )
-         ISV   = IE
-         JWORK = ISV + NCOL
-         CALL DGELSS( NCOL, NCOL, 1, DWORK(INIR), LDR, DWORK(INIH), LDR,
-     $                DWORK(ISV), TOLL, RANK, DWORK(JWORK),
-     $                LDWORK-JWORK+1, IERR )
-         IF ( IERR.GT.0 ) THEN
-C
-C           Return if SVD algorithm did not converge.
-C
-            INFO = 2
-            RETURN
-         END IF
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) - JWORK + 1 )
-      ELSE
-C
-C        Find the least squares solution using QR decomposition only.
-C
-         CALL DTRSM( 'Left', 'Upper', 'No Transpose', 'Non Unit', NCOL,
-     $               1, ONE, DWORK(INIR), LDR, DWORK(INIH), LDR )
-      END IF
-C
-C     Setup the estimated n-by-m input matrix  B,  and the estimated
-C     initial state of the system  x0.
-C
-      CALL DLACPY( 'Full', N, M, DWORK(INIH), N, B, LDB )
-C
-      IF ( N.GT.0 .AND. WITHX0 ) THEN
-         CALL DCOPY( N, DWORK(INIH+NM), 1, X0, 1 )
-      ELSE
-         CALL DCOPY( N, DUM, 0, X0, 1 )
-      END IF
-C
-      IF ( M.GT.0 .AND. WITHD ) THEN
-C
-C        Compute the estimated l-by-m input/output matrix  D.
-C
-         IF ( NCYC ) THEN
-            IRHS = INIS + LM*NCOL
-            CALL DGEMV( 'No Transpose', LM, NCOL, -ONE, DWORK(INIS),
-     $                  LM, DWORK(INIH), 1, ONE, DWORK(IRHS), 1 )
-         ELSE
-C
-            DO 200 K = 1, L
-               CALL DGEMV( 'No Transpose', M, NCOL, -ONE,
-     $                     DWORK(INIS+(K-1)*NOBS), LDDW, DWORK(INIH), 1,
-     $                     ONE, DWORK(IRHS+(K-1)*NOBS), 1 )
-  200       CONTINUE
-C
-            DO 210 K = 2, L
-               CALL DCOPY( M, DWORK(IRHS+(K-1)*NOBS), 1,
-     $                     DWORK(IRHS+(K-1)*M), 1 )
-  210       CONTINUE
-C
-         END IF
-C
-C        Estimate the reciprocal condition number of the triangular
-C        factor of the QR decomposition of the matrix U.
-C        Workspace: need  u + 3*M.
-C
-         CALL DTRCON( '1-norm', 'Upper', 'No Transpose', M, U, LDU,
-     $                RCONDU, DWORK(IE), IWORK, IERR )
-         IF ( RCONDU.LE.TOLL**( TWO/THREE ) ) THEN
-            IWARN = 4
-C
-C           The least squares problem is ill-conditioned.
-C           Use SVD to solve it. (QR decomposition of  U  is preserved.)
-C           Workspace: need   u + 2*M*M + 6*M;
-C                      prefer larger.
-C
-            IQ    = IE  + M*M
-            ISV   = IQ  + M*M
-            JWORK = ISV + M
-            CALL DLACPY( 'Upper', M, M, U, LDU, DWORK(IE), M )
-            CALL MB02UD( 'Not Factored', 'Left', 'No Transpose',
-     $                   'No Pinv', M, L, ONE, TOLL, RANK, DWORK(IE),
-     $                   M, DWORK(IQ), M, DWORK(ISV), DWORK(IRHS), M,
-     $                   DUM, 1, DWORK(JWORK), LDWORK-JWORK+1, IERR )
-            IF ( IERR.GT.0 ) THEN
-C
-C              Return if SVD algorithm did not converge.
-C
-               INFO = 2
-               RETURN
-            END IF
-            MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) - JWORK + 1 )
-         ELSE
-            CALL DTRSM( 'Left', 'Upper', 'No Transpose', 'Non Unit', M,
-     $                  L, ONE, U, LDU, DWORK(IRHS), M )
-         END IF
-         CALL MA02AD( 'Full', M, L, DWORK(IRHS), M, D, LDD )
-C
-      END IF
-C
-      DWORK(1) = MAXWRK
-      DWORK(2) = RCOND
-      IF ( M.GT.0 .AND. WITHD )
-     $   DWORK(3) = RCONDU
-C
-      RETURN
-C
-C *** End of IB01QD ***
-      END
--- a/extra/control-devel/src/IB01RD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,762 +0,0 @@
-      SUBROUTINE IB01RD( JOB, N, M, L, NSMP, A, LDA, B, LDB, C, LDC, D,
-     $                   LDD, U, LDU, Y, LDY, X0, TOL, IWORK, DWORK,
-     $                   LDWORK, IWARN, 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 estimate the initial state of a linear time-invariant (LTI)
-C     discrete-time system, given the system matrices  (A,B,C,D)  and
-C     the input and output trajectories of the system. The model
-C     structure is :
-C
-C           x(k+1) = Ax(k) + Bu(k),   k >= 0,
-C           y(k)   = Cx(k) + Du(k),
-C
-C     where  x(k)  is the  n-dimensional state vector (at time k),
-C            u(k)  is the  m-dimensional input vector,
-C            y(k)  is the  l-dimensional output vector,
-C     and  A, B, C, and D  are real matrices of appropriate dimensions.
-C     Matrix  A  is assumed to be in a real Schur form.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies whether or not the matrix D is zero, as follows:
-C             = 'Z':  the matrix  D  is zero;
-C             = 'N':  the matrix  D  is not zero.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the system.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs.  M >= 0.
-C
-C     L       (input) INTEGER
-C             The number of system outputs.  L > 0.
-C
-C     NSMP    (input) INTEGER
-C             The number of rows of matrices  U  and  Y  (number of
-C             samples used,  t).  NSMP >= N.
-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  in a real Schur form.
-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  (corresponding to the real Schur
-C             form of  A).
-C             If  N = 0  or  M = 0,  this array is not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.
-C             LDB >= N,  if  N > 0  and  M > 0;
-C             LDB >= 1,  if  N = 0  or   M = 0.
-C
-C     C       (input) DOUBLE PRECISION array, dimension (LDC,N)
-C             The leading L-by-N part of this array must contain the
-C             system output matrix  C  (corresponding to the real Schur
-C             form of  A).
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.  LDC >= L.
-C
-C     D       (input) DOUBLE PRECISION array, dimension (LDD,M)
-C             The leading L-by-M part of this array must contain the
-C             system input-output matrix.
-C             If  M = 0  or  JOB = 'Z',  this array is not referenced.
-C
-C     LDD     INTEGER
-C             The leading dimension of the array D.
-C             LDD >= L,  if  M > 0  and  JOB = 'N';
-C             LDD >= 1,  if  M = 0  or   JOB = 'Z'.
-C
-C     U       (input) DOUBLE PRECISION array, dimension (LDU,M)
-C             If  M > 0,  the leading NSMP-by-M part of this array must
-C             contain the t-by-m input-data sequence matrix  U,
-C             U = [u_1 u_2 ... u_m].  Column  j  of  U  contains the
-C             NSMP  values of the j-th input component for consecutive
-C             time increments.
-C             If M = 0, this array is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of the array U.
-C             LDU >= MAX(1,NSMP),  if M > 0;
-C             LDU >= 1,            if M = 0.
-C
-C     Y       (input) DOUBLE PRECISION array, dimension (LDY,L)
-C             The leading NSMP-by-L part of this array must contain the
-C             t-by-l output-data sequence matrix  Y,
-C             Y = [y_1 y_2 ... y_l].  Column  j  of  Y  contains the
-C             NSMP  values of the j-th output component for consecutive
-C             time increments.
-C
-C     LDY     INTEGER
-C             The leading dimension of the array Y.  LDY >= MAX(1,NSMP).
-C
-C     X0      (output) DOUBLE PRECISION array, dimension (N)
-C             The estimated initial state of the system,  x(0).
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used for estimating the rank of
-C             matrices. If the user sets  TOL > 0,  then the given value
-C             of  TOL  is used as a lower bound for the reciprocal
-C             condition number;  a matrix whose estimated condition
-C             number is less than  1/TOL  is considered to be of full
-C             rank.  If the user sets  TOL <= 0,  then  EPS  is used
-C             instead, where  EPS  is the relative machine precision
-C             (see LAPACK Library routine DLAMCH).  TOL <= 1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of LDWORK and  DWORK(2)  contains the reciprocal condition
-C             number of the triangular factor of the QR factorization of
-C             the matrix  Gamma  (see METHOD).
-C             On exit, if  INFO = -22,  DWORK(1)  returns the minimum
-C             value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= max( 2, min( LDW1, LDW2 ) ),  where
-C             LDW1 = t*L*(N + 1) + 2*N + max( 2*N*N, 4*N ),
-C             LDW2 =   N*(N + 1) + 2*N +
-C                      max( q*(N + 1) + 2*N*N + L*N, 4*N ),
-C                q = N*L.
-C             For good performance,  LDWORK  should be larger.
-C             If  LDWORK >= LDW1,  then standard QR factorization of
-C             the matrix  Gamma  (see METHOD) is used. Otherwise, the
-C             QR factorization is computed sequentially by performing
-C             NCYCLE  cycles, each cycle (except possibly the last one)
-C             processing  s  samples, where  s  is chosen by equating
-C             LDWORK  to  LDW2,  for  q  replaced by  s*L.
-C             The computational effort may increase and the accuracy may
-C             decrease with the decrease of  s.  Recommended value is
-C             LDRWRK = LDW1,  assuming a large enough cache size, to
-C             also accommodate  A, B, C, D, U,  and  Y.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 4:  the least squares problem to be solved has a
-C                   rank-deficient coefficient matrix.
-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             = 2:  the singular value decomposition (SVD) algorithm did
-C                   not converge.
-C
-C     METHOD
-C
-C     An extension and refinement of the method in [1] is used.
-C     Specifically, the output y0(k) of the system for zero initial
-C     state is computed for k = 0, 1, ...,  t-1 using the given model.
-C     Then the following least squares problem is solved for x(0)
-C
-C                         (     C     )            (   y(0) - y0(0)   )
-C                         (    C*A    )            (   y(1) - y0(1)   )
-C        Gamma * x(0)  =  (     :     ) * x(0)  =  (        :         ).
-C                         (     :     )            (        :         )
-C                         ( C*A^(t-1) )            ( y(t-1) - y0(t-1) )
-C
-C     The coefficient matrix  Gamma  is evaluated using powers of A with
-C     exponents 2^k. The QR decomposition of this matrix is computed.
-C     If its triangular factor  R  is too ill conditioned, then singular
-C     value decomposition of  R  is used.
-C
-C     If the coefficient matrix cannot be stored in the workspace (i.e.,
-C     LDWORK < LDW1),  the QR decomposition is computed sequentially.
-C
-C     REFERENCES
-C
-C     [1] Verhaegen M., and Varga, A.
-C         Some Experience with the MOESP Class of Subspace Model
-C         Identification Methods in Identifying the BO105 Helicopter.
-C         Report TR R165-94, DLR Oberpfaffenhofen, 1994.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is numerically stable.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 2000.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Feb. 2004.
-C
-C     KEYWORDS
-C
-C     Identification methods; least squares solutions; multivariable
-C     systems; QR decomposition; singular value decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, THREE
-      PARAMETER          ( ZERO  = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
-     $                     THREE = 3.0D0 )
-C     IBLOCK is a threshold value for switching to a block algorithm
-C     for  U  (to avoid row by row passing through  U).
-      INTEGER            IBLOCK
-      PARAMETER          ( IBLOCK = 16384 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION   TOL
-      INTEGER            INFO, IWARN, L, LDA, LDB, LDC, LDD, LDU,
-     $                   LDWORK, LDY, M, N, NSMP
-      CHARACTER          JOB
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA, *), B(LDB, *), C(LDC, *), D(LDD, *),
-     $                   DWORK(*),  U(LDU, *), X0(*), Y(LDY, *)
-      INTEGER            IWORK(*)
-C     .. Local Scalars ..
-      DOUBLE PRECISION   RCOND, TOLL
-      INTEGER            I2, IA, IAS, IC, ICYCLE, IE, IERR, IEXPON,
-     $                   IG, INIGAM, INIH, INIR, INIT, IQ, IREM, IRHS,
-     $                   ISIZE, ISV, ITAU, IU, IUPNT, IUT, IUTRAN, IX,
-     $                   IXINIT, IY, IYPNT, J, JWORK, K, LDDW, LDR,
-     $                   LDW1, LDW2, MAXWRK, MINSMP, MINWLS, MINWRK, NC,
-     $                   NCP1, NCYCLE, NN, NOBS, NRBL, NROW, NSMPL, RANK
-      LOGICAL            BLOCK, FIRST, NCYC, POWER2, SWITCH, WITHD
-C     .. Local Arrays ..
-      DOUBLE PRECISION   DUM(1)
-C     .. External Functions ..
-      LOGICAL            LSAME
-      INTEGER            ILAENV
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           DLAMCH, ILAENV, LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DAXPY, DCOPY, DGELSS, DGEMV, DGEQRF, DLACPY,
-     $                   DLASET, DORMQR, DTRCON, DTRMM, DTRMV, DTRSV,
-     $                   MA02AD, MB01TD, MB04OD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          DBLE, INT, LOG, MAX, MIN, MOD
-C     .. Executable Statements ..
-C
-C     Check the input parameters.
-C
-      WITHD  = LSAME( JOB, 'N' )
-      IWARN  = 0
-      INFO   = 0
-      NN     = N*N
-      MINSMP = N
-C
-      IF( .NOT.( LSAME( JOB, 'Z' ) .OR. WITHD ) ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( L.LE.0 ) THEN
-         INFO = -4
-      ELSE IF( NSMP.LT.MINSMP ) THEN
-         INFO = -5
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( LDB.LT.1 .OR. ( LDB.LT.N .AND. M.GT.0 ) ) THEN
-         INFO = -9
-      ELSE IF( LDC.LT.L ) THEN
-         INFO = -11
-      ELSE IF( LDD.LT.1 .OR. ( WITHD .AND. LDD.LT.L .AND. M.GT.0 ) )
-     $      THEN
-         INFO = -13
-      ELSE IF( LDU.LT.1 .OR. ( M.GT.0 .AND. LDU.LT.NSMP ) ) THEN
-         INFO = -15
-      ELSE IF( LDY.LT.MAX( 1, NSMP ) ) THEN
-         INFO = -17
-      ELSE IF( TOL.GT.ONE ) THEN
-         INFO = -19
-      END IF
-C
-C     Compute workspace.
-C      (Note: Comments in the code beginning "Workspace:" describe the
-C       minimal amount of workspace needed at that point in the code,
-C       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
-      NSMPL  = NSMP*L
-      IQ     = MINSMP*L
-      NCP1   = N + 1
-      ISIZE  = NSMPL*NCP1
-      IC     = 2*NN
-      MINWLS = MINSMP*NCP1
-      ITAU   = IC + L*N
-      LDW1   = ISIZE  + 2*N + MAX( IC, 4*N )
-      LDW2   = MINWLS + 2*N + MAX( IQ*NCP1 + ITAU, 4*N )
-      MINWRK = MAX( MIN( LDW1, LDW2 ), 2 )
-      IF ( INFO.EQ.0 .AND. LDWORK.GE.MINWRK ) THEN
-         MAXWRK = ISIZE + 2*N + MAX( N*ILAENV( 1, 'DGEQRF', ' ', NSMPL,
-     $                                         N, -1, -1 ),
-     $                               ILAENV( 1, 'DORMQR', 'LT', NSMPL,
-     $                                       1, N, -1 ) )
-         MAXWRK = MAX( MAXWRK, MINWRK )
-      END IF
-C
-      IF ( INFO.EQ.0 .AND. LDWORK.LT.MINWRK ) THEN
-         INFO = -22
-         DWORK(1) = MINWRK
-      END IF
-C
-C     Return if there are illegal arguments.
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'IB01RD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( N.EQ.0 ) THEN
-         DWORK(1) = TWO
-         DWORK(2) = ONE
-         RETURN
-      END IF
-C
-C     Set up the least squares problem, either directly, if enough
-C     workspace, or sequentially, otherwise.
-C
-      IYPNT = 1
-      IUPNT = 1
-      INIR  = 1
-      IF ( LDWORK.GE.LDW1 ) THEN
-C
-C        Enough workspace for solving the problem directly.
-C
-         NCYCLE = 1
-         NOBS   = NSMP
-         LDDW   = NSMPL
-         INIGAM = 1
-      ELSE
-C
-C        NCYCLE > 1  cycles are needed for solving the problem
-C        sequentially, taking  NOBS  samples in each cycle (or the
-C        remaining samples in the last cycle).
-C
-         JWORK  = LDWORK - MINWLS - 2*N - ITAU
-         LDDW   = JWORK/NCP1
-         NOBS   = LDDW/L
-         LDDW   = L*NOBS
-         NCYCLE = NSMP/NOBS
-         IF ( MOD( NSMP, NOBS ).NE.0 )
-     $      NCYCLE = NCYCLE + 1
-         INIH   = INIR + NN
-         INIGAM = INIH + N
-      END IF
-C
-      NCYC   = NCYCLE.GT.1
-      IRHS   = INIGAM + LDDW*N
-      IXINIT = IRHS   + LDDW
-      IC     = IXINIT + N
-      IF( NCYC ) THEN
-         IA   = IC + L*N
-         LDR  = N
-         IE   = INIGAM
-      ELSE
-         INIH = IRHS
-         IA   = IC
-         LDR  = LDDW
-         IE   = IXINIT
-      END IF
-      IUTRAN = IA
-      IAS    = IA + NN
-      ITAU   = IA
-      DUM(1) = ZERO
-C
-C     Set block parameters for passing through the array  U.
-C
-      BLOCK = M.GT.1 .AND. NSMP*M.GE.IBLOCK
-      IF ( BLOCK ) THEN
-         NRBL = ( LDWORK - IUTRAN + 1 )/M
-         NC   = NOBS/NRBL
-         IF ( MOD( NOBS, NRBL ).NE.0 )
-     $      NC = NC + 1
-         INIT  = ( NC - 1 )*NRBL
-         BLOCK = BLOCK .AND. NRBL.GT.1
-      END IF
-C
-C     Perform direct of sequential compression of the matrix  Gamma.
-C
-      DO 150 ICYCLE = 1, NCYCLE
-         FIRST = ICYCLE.EQ.1
-         IF ( .NOT.FIRST ) THEN
-            IF ( ICYCLE.EQ.NCYCLE ) THEN
-               NOBS = NSMP - ( NCYCLE - 1 )*NOBS
-               LDDW = L*NOBS
-               IF ( BLOCK ) THEN
-                  NC = NOBS/NRBL
-                  IF ( MOD( NOBS, NRBL ).NE.0 )
-     $               NC = NC + 1
-                  INIT = ( NC - 1 )*NRBL
-               END IF
-            END IF
-         END IF
-C
-C        Compute the extended observability matrix  Gamma.
-C        Workspace: need   s*L*(N + 1) + 2*N*N + 2*N + a + w,
-C                   where  s = NOBS,
-C                          a = 0,   w = 0,          if NCYCLE = 1,
-C                          a = L*N, w = N*(N + 1),  if NCYCLE > 1;
-C                   prefer as above, with  s = t,  a = w = 0.
-C
-         JWORK  = IAS + NN
-         IEXPON = INT( LOG( DBLE( NOBS ) )/LOG( TWO ) )
-         IREM   = L*( NOBS - 2**IEXPON )
-         POWER2 = IREM.EQ.0
-         IF ( .NOT.POWER2 )
-     $      IEXPON = IEXPON + 1
-C
-         IF ( FIRST ) THEN
-            CALL DLACPY( 'Full', L, N, C, LDC, DWORK(INIGAM), LDDW )
-         ELSE
-            CALL DLACPY( 'Full', L, N, DWORK(IC), L, DWORK(INIGAM),
-     $                   LDDW )
-         END IF
-C                                       p
-C        Use powers of the matrix  A:  A ,  p = 2**(J-1).
-C
-         CALL DLACPY( 'Upper', N, N, A, LDA, DWORK(IA), N )
-         IF ( N.GT.1 )
-     $      CALL DCOPY( N-1, A(2,1), LDA+1, DWORK(IA+1), N+1 )
-         I2   = L
-         NROW = 0
-C
-         DO 20 J = 1, IEXPON
-            IG = INIGAM
-            IF ( J.LT.IEXPON .OR. POWER2 ) THEN
-               NROW = I2
-            ELSE
-               NROW = IREM
-            END IF
-C
-            CALL DLACPY( 'Full', NROW, N, DWORK(IG), LDDW, DWORK(IG+I2),
-     $                   LDDW )
-            CALL DTRMM(  'Right', 'Upper', 'No Transpose', 'Non Unit',
-     $                   NROW, N, ONE, DWORK(IA), N, DWORK(IG+I2),
-     $                   LDDW )
-C                                                            p
-C           Compute the contribution of the subdiagonal of  A   to the
-C           product.
-C
-            DO 10 IX = 1, N - 1
-               CALL DAXPY( NROW, DWORK(IA+(IX-1)*N+IX), DWORK(IG+LDDW),
-     $                     1, DWORK(IG+I2), 1 )
-               IG = IG + LDDW
-   10       CONTINUE
-C
-            IF ( J.LT.IEXPON ) THEN
-               CALL DLACPY( 'Upper', N, N, DWORK(IA), N, DWORK(IAS), N )
-               CALL DCOPY(  N-1, DWORK(IA+1), N+1, DWORK(IAS+1), N+1 )
-               CALL MB01TD( N, DWORK(IAS), N, DWORK(IA), N,
-     $                      DWORK(JWORK), IERR )
-               I2 = I2*2
-            END IF
-   20    CONTINUE
-C
-         IF ( NCYC ) THEN
-            IG = INIGAM + I2 + NROW - L
-            CALL DLACPY( 'Full', L, N, DWORK(IG), LDDW, DWORK(IC), L )
-            CALL DTRMM( 'Right', 'Upper', 'No Transpose', 'Non Unit', L,
-     $                  N, ONE, A, LDA, DWORK(IC), L )
-C
-C           Compute the contribution of the subdiagonal of  A  to the
-C           product.
-C
-            DO 30 IX = 1, N - 1
-               CALL DAXPY( L, A(IX+1,IX), DWORK(IG+LDDW), 1,
-     $                     DWORK(IC+(IX-1)*L), 1 )
-               IG = IG + LDDW
-   30       CONTINUE
-C
-         END IF
-C
-C        Setup (part of) the right hand side of the least squares
-C        problem starting from  DWORK(IRHS);  use the estimated output
-C        trajectory for zero initial state, or for the saved final state
-C        value of the previous cycle.
-C        A specialization of SLICOT Library routine TF01ND is used.
-C        For large input sets  (NSMP*M >= IBLOCK),  chunks of  U  are
-C        transposed, to reduce the number of row-wise passes.
-C        Workspace: need   s*L*(N + 1) + N + w;
-C                   prefer as above, with  s = t,  w = 0.
-C
-         IF ( FIRST )
-     $      CALL DCOPY( N, DUM, 0, DWORK(IXINIT), 1 )
-         CALL DCOPY( N, DWORK(IXINIT), 1, X0, 1 )
-         IY = IRHS
-C
-         DO 40 J = 1, L
-            CALL DCOPY( NOBS, Y(IYPNT,J), 1, DWORK(IY), L )
-            IY = IY + 1
-   40    CONTINUE
-C
-         IY = IRHS
-         IU = IUPNT
-         IF ( M.GT.0 ) THEN
-            IF ( WITHD ) THEN
-C
-               IF ( BLOCK ) THEN
-                  SWITCH = .TRUE.
-                  NROW   = NRBL
-C
-                  DO 60 K = 1, NOBS
-                     IF ( MOD( K-1, NROW ).EQ.0 .AND. SWITCH ) THEN
-                        IUT = IUTRAN
-                        IF ( K.GT.INIT ) THEN
-                           NROW = NOBS - INIT
-                           SWITCH = .FALSE.
-                        END IF
-                        CALL MA02AD( 'Full', NROW, M, U(IU,1), LDU,
-     $                               DWORK(IUT), M )
-                        IU = IU + NROW
-                     END IF
-                     CALL DGEMV( 'No transpose', L, N, -ONE, C, LDC, X0,
-     $                           1, ONE, DWORK(IY), 1 )
-                     CALL DGEMV( 'No transpose', L, M, -ONE, D, LDD,
-     $                           DWORK(IUT), 1, ONE, DWORK(IY), 1 )
-                     CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', N,
-     $                           A, LDA, X0, 1 )
-C
-                     DO 50 IX = 2, N
-                        X0(IX) = X0(IX) + A(IX,IX-1)*DWORK(IXINIT+IX-2)
-   50                CONTINUE
-C
-                     CALL DGEMV( 'No transpose', N, M, ONE, B, LDB,
-     $                           DWORK(IUT), 1, ONE, X0, 1 )
-                     CALL DCOPY( N, X0, 1, DWORK(IXINIT), 1 )
-                     IY  = IY  + L
-                     IUT = IUT + M
-   60             CONTINUE
-C
-               ELSE
-C
-                  DO 80 K = 1, NOBS
-                     CALL DGEMV( 'No transpose', L, N, -ONE, C, LDC, X0,
-     $                           1, ONE, DWORK(IY), 1 )
-                     CALL DGEMV( 'No transpose', L, M, -ONE, D, LDD,
-     $                           U(IU,1), LDU, ONE, DWORK(IY), 1 )
-                     CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', N,
-     $                           A, LDA, X0, 1 )
-C
-                     DO 70 IX = 2, N
-                        X0(IX) = X0(IX) + A(IX,IX-1)*DWORK(IXINIT+IX-2)
-   70                CONTINUE
-C
-                     CALL DGEMV( 'No transpose', N, M, ONE, B, LDB,
-     $                           U(IU,1), LDU, ONE, X0, 1 )
-                     CALL DCOPY( N, X0, 1, DWORK(IXINIT), 1 )
-                     IY = IY + L
-                     IU = IU + 1
-   80             CONTINUE
-C
-               END IF
-C
-            ELSE
-C
-               IF ( BLOCK ) THEN
-                  SWITCH = .TRUE.
-                  NROW   = NRBL
-C
-                  DO 100 K = 1, NOBS
-                     IF ( MOD( K-1, NROW ).EQ.0 .AND. SWITCH ) THEN
-                        IUT = IUTRAN
-                        IF ( K.GT.INIT ) THEN
-                           NROW = NOBS - INIT
-                           SWITCH = .FALSE.
-                        END IF
-                        CALL MA02AD( 'Full', NROW, M, U(IU,1), LDU,
-     $                               DWORK(IUT), M )
-                        IU = IU + NROW
-                     END IF
-                     CALL DGEMV( 'No transpose', L, N, -ONE, C, LDC, X0,
-     $                           1, ONE, DWORK(IY), 1 )
-                     CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', N,
-     $                           A, LDA, X0, 1 )
-C
-                     DO 90 IX = 2, N
-                        X0(IX) = X0(IX) + A(IX,IX-1)*DWORK(IXINIT+IX-2)
-   90                CONTINUE
-C
-                     CALL DGEMV( 'No transpose', N, M, ONE, B, LDB,
-     $                           DWORK(IUT), 1, ONE, X0, 1 )
-                     CALL DCOPY( N, X0, 1, DWORK(IXINIT), 1 )
-                     IY  = IY  + L
-                     IUT = IUT + M
-  100             CONTINUE
-C
-               ELSE
-C
-                  DO 120 K = 1, NOBS
-                     CALL DGEMV( 'No transpose', L, N, -ONE, C, LDC, X0,
-     $                           1, ONE, DWORK(IY), 1 )
-                     CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', N,
-     $                           A, LDA, X0, 1 )
-C
-                     DO 110 IX = 2, N
-                        X0(IX) = X0(IX) + A(IX,IX-1)*DWORK(IXINIT+IX-2)
-  110                CONTINUE
-C
-                     CALL DGEMV( 'No transpose', N, M, ONE, B, LDB,
-     $                           U(IU,1), LDU, ONE, X0, 1 )
-                     CALL DCOPY( N, X0, 1, DWORK(IXINIT), 1 )
-                     IY = IY + L
-                     IU = IU + 1
-  120             CONTINUE
-C
-               END IF
-C
-            END IF
-C
-         ELSE
-C
-            DO 140 K = 1, NOBS
-               CALL DGEMV( 'No transpose', L, N, -ONE, C, LDC, X0, 1,
-     $                     ONE, DWORK(IY), 1 )
-               CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', N, A,
-     $                     LDA, X0, 1 )
-C
-               DO 130 IX = 2, N
-                  X0(IX) = X0(IX) + A(IX,IX-1)*DWORK(IXINIT+IX-2)
-  130          CONTINUE
-C
-               CALL DCOPY( N, X0, 1, DWORK(IXINIT), 1 )
-               IY = IY + L
-  140       CONTINUE
-C
-         END IF
-C
-C        Compress the data using (sequential) QR factorization.
-C        Workspace: need   v + 2*N;
-C                   where  v = s*L*(N + 1) + N + a + w.
-C
-         JWORK = ITAU + N
-         IF ( FIRST ) THEN
-C
-C           Compress the first data segment of  Gamma.
-C           Workspace: need   v + 2*N,
-C                      prefer v + N + N*NB.
-C
-            CALL DGEQRF( LDDW, N, DWORK(INIGAM), LDDW, DWORK(ITAU),
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-C           Apply the transformation to the right hand side part.
-C           Workspace: need   v + N + 1,
-C                      prefer v + N + NB.
-C
-            CALL DORMQR( 'Left', 'Transpose', LDDW, 1, N, DWORK(INIGAM),
-     $                   LDDW, DWORK(ITAU), DWORK(IRHS), LDDW,
-     $                   DWORK(JWORK), LDWORK-JWORK+1, IERR )
-C
-            IF ( NCYC ) THEN
-C
-C              Save the triangular factor of  Gamma  and the
-C              corresponding right hand side.
-C
-               CALL DLACPY( 'Upper', N, NCP1, DWORK(INIGAM), LDDW,
-     $                      DWORK(INIR), LDR )
-            END IF
-         ELSE
-C
-C           Compress the current (but not the first) data segment of
-C           Gamma.
-C           Workspace: need   v + N - 1.
-C
-            CALL MB04OD( 'Full', N, 1,  LDDW, DWORK(INIR), LDR,
-     $                   DWORK(INIGAM), LDDW, DWORK(INIH), LDR,
-     $                   DWORK(IRHS), LDDW, DWORK(ITAU), DWORK(JWORK) )
-         END IF
-C
-         IUPNT = IUPNT + NOBS
-         IYPNT = IYPNT + NOBS
-  150 CONTINUE
-C
-C     Estimate the reciprocal condition number of the triangular factor
-C     of the QR decomposition.
-C     Workspace: need  u + 3*N, where
-C                      u = t*L*(N + 1), if NCYCLE = 1;
-C                      u = w,           if NCYCLE > 1.
-C
-      CALL DTRCON( '1-norm', 'Upper', 'No Transpose', N, DWORK(INIR),
-     $             LDR, RCOND, DWORK(IE), IWORK, IERR )
-C
-      TOLL = TOL
-      IF ( TOLL.LE.ZERO )
-     $   TOLL = DLAMCH( 'Precision' )
-      IF ( RCOND.LE.TOLL**( TWO/THREE ) ) THEN
-         IWARN = 4
-C
-C        The least squares problem is ill-conditioned.
-C        Use SVD to solve it.
-C        Workspace: need   u + 6*N;
-C                   prefer larger.
-C
-         CALL DLASET( 'Lower', N-1, N-1, ZERO, ZERO, DWORK(INIR+1),
-     $                LDR )
-         ISV   = IE
-         JWORK = ISV + N
-         CALL DGELSS( N, N, 1, DWORK(INIR), LDR, DWORK(INIH), LDR,
-     $                DWORK(ISV), TOLL, RANK, DWORK(JWORK),
-     $                LDWORK-JWORK+1, IERR )
-         IF ( IERR.GT.0 ) THEN
-C
-C           Return if SVD algorithm did not converge.
-C
-            INFO = 2
-            RETURN
-         END IF
-         MAXWRK = MAX( MAXWRK, INT( DWORK(JWORK) ) - JWORK + 1 )
-      ELSE
-C
-C        Find the least squares solution using QR decomposition only.
-C
-         CALL DTRSV( 'Upper', 'No Transpose', 'Non Unit', N,
-     $               DWORK(INIR), LDR, DWORK(INIH), 1 )
-      END IF
-C
-C     Return the estimated initial state of the system  x0.
-C
-      CALL DCOPY( N, DWORK(INIH), 1, X0, 1 )
-C
-      DWORK(1) = MAXWRK
-      DWORK(2) = RCOND
-C
-      RETURN
-C
-C *** End of IB01RD ***
-      END
--- a/extra/control-devel/src/MA02AD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,108 +0,0 @@
-      SUBROUTINE MA02AD( JOB, M, N, A, LDA, B, LDB )
-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 transpose all or part of a two-dimensional matrix A into
-C     another matrix B.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies the part of the matrix A to be transposed into B
-C             as follows:
-C             = 'U': Upper triangular part;
-C             = 'L': Lower triangular part;
-C             Otherwise:  All of the matrix A.
-C
-C     Input/Output Parameters
-C
-C     M      (input) INTEGER
-C            The number of rows of the matrix A.  M >= 0.
-C
-C     N      (input) INTEGER
-C            The number of columns of the matrix A.  N >= 0.
-C
-C     A      (input) DOUBLE PRECISION array, dimension (LDA,N)
-C            The m-by-n matrix A.  If JOB = 'U', only the upper
-C            triangle or trapezoid is accessed; if JOB = 'L', only the
-C            lower triangle or trapezoid is accessed.
-C
-C     LDA    INTEGER
-C            The leading dimension of the array A.  LDA >= max(1,M).
-C
-C     B      (output) DOUBLE PRECISION array, dimension (LDB,M)
-C            B = A' in the locations specified by JOB.
-C
-C     LDB    INTEGER
-C            The leading dimension of the array B.  LDB >= max(1,N).
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, March 1998.
-C     Based on the RASP routine DMTRA.
-C
-C     REVISIONS
-C
-C     -
-C
-C     ******************************************************************
-C
-C     .. Scalar Arguments ..
-      CHARACTER          JOB
-      INTEGER            LDA, LDB, M, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA,*), B(LDB,*)
-C     .. Local Scalars ..
-      INTEGER            I, J
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     .. Intrinsic Functions ..
-      INTRINSIC          MIN
-C
-C     .. Executable Statements ..
-C
-      IF( LSAME( JOB, 'U' ) ) THEN
-         DO 20 J = 1, N
-            DO 10 I = 1, MIN( J, M )
-               B(J,I) = A(I,J)
-   10       CONTINUE
-   20    CONTINUE
-      ELSE IF( LSAME( JOB, 'L' ) ) THEN
-         DO 40 J = 1, N
-            DO 30 I = J, M
-               B(J,I) = A(I,J)
-   30       CONTINUE
-   40    CONTINUE
-      ELSE
-         DO 60 J = 1, N
-            DO 50 I = 1, M
-               B(J,I) = A(I,J)
-   50       CONTINUE
-   60    CONTINUE
-      END IF
-C
-      RETURN
-C *** Last line of MA02AD ***
-      END
--- a/extra/control-devel/src/MA02BD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +0,0 @@
-      SUBROUTINE MA02BD( SIDE, M, N, A, LDA )
-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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To reverse the order of rows and/or columns of a given matrix A
-C     by pre-multiplying and/or post-multiplying it, respectively, with
-C     a permutation matrix P, where P is a square matrix of appropriate
-C     order, with ones down the secondary diagonal.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     SIDE    CHARACTER*1
-C             Specifies the operation to be performed, as follows:
-C             = 'L': the order of rows of A is to be reversed by
-C                    pre-multiplying A with P;
-C             = 'R': the order of columns of A is to be reversed by
-C                    post-multiplying A with P;
-C             = 'B': both the order of rows and the order of columns
-C                    of A is to be reversed by pre-multiplying and
-C                    post-multiplying A with P.
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrix A.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrix A.  N >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading M-by-N part of this array must
-C             contain the given matrix whose rows and/or columns are to
-C             be permuted.
-C             On exit, the leading M-by-N part of this array contains
-C             the matrix P*A if SIDE = 'L', or A*P if SIDE = 'R', or
-C             P*A*P if SIDE = 'B'.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,M).
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, March 1998.
-C     Based on the RASP routine PAP.
-C
-C     REVISIONS
-C
-C     -
-C
-C    ******************************************************************
-C
-C     .. Scalar Arguments ..
-      CHARACTER          SIDE
-      INTEGER            LDA, M, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA,*)
-C     .. Local Scalars ..
-      LOGICAL            BSIDES
-      INTEGER            I, J, K, M2, N2
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DSWAP
-C     .. Executable Statements ..
-C
-      BSIDES  = LSAME( SIDE, 'B' )
-C
-      IF( ( LSAME( SIDE, 'L' ) .OR. BSIDES ) .AND. M.GT.1 ) THEN
-C
-C        Compute P*A.
-C
-         M2 = M/2
-         K = M - M2 + 1
-         DO 10 J = 1, N
-            CALL DSWAP( M2, A(1,J), -1, A(K,J), 1 )
-   10    CONTINUE
-      END IF
-      IF( ( LSAME( SIDE, 'R' ) .OR. BSIDES ) .AND. N.GT.1 ) THEN
-C
-C        Compute A*P.
-C
-         N2 = N/2
-         K = N - N2 + 1
-         DO 20 I = 1, M
-            CALL DSWAP( N2, A(I,1), -LDA, A(I,K), LDA )
-   20    CONTINUE
-      END IF
-C
-      RETURN
-C *** Last line of MA02BD ***
-      END
--- a/extra/control-devel/src/MA02DD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +0,0 @@
-      SUBROUTINE MA02DD( JOB, UPLO, N, A, LDA, AP )
-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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To pack/unpack the upper or lower triangle of a symmetric matrix.
-C     The packed matrix is stored column-wise in the one-dimensional
-C     array AP.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies whether the matrix should be packed or unpacked,
-C             as follows:
-C             = 'P':  The matrix should be packed;
-C             = 'U':  The matrix should be unpacked.
-C
-C     UPLO    CHARACTER*1
-C             Specifies the part of the matrix to be packed/unpacked,
-C             as follows:
-C             = 'U':  Upper triangular part;
-C             = 'L':  Lower triangular part.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix A.  N >= 0.
-C
-C     A       (input or output) DOUBLE PRECISION array, dimension
-C             (LDA,N)
-C             This array is an input parameter if JOB = 'P', and an
-C             output parameter if JOB = 'U'.
-C             On entry, if JOB = 'P', the leading N-by-N upper
-C             triangular part (if UPLO = 'U'), or lower triangular part
-C             (if UPLO = 'L'), of this array must contain the
-C             corresponding upper or lower triangle of the symmetric
-C             matrix A, and the other strictly triangular part is not
-C             referenced.
-C             On exit, if JOB = 'U', the leading N-by-N upper triangular
-C             part (if UPLO = 'U'), or lower triangular part (if
-C             UPLO = 'L'), of this array contains the corresponding
-C             upper or lower triangle of the symmetric matrix A; the
-C             other strictly triangular part is not referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,N).
-C
-C     AP      (output or input) DOUBLE PRECISION array, dimension
-C             (N*(N+1)/2)
-C             This array is an output parameter if JOB = 'P', and an
-C             input parameter if JOB = 'U'.
-C             On entry, if JOB = 'U', the leading N*(N+1)/2 elements of
-C             this array must contain the upper (if UPLO = 'U') or lower
-C             (if UPLO = 'L') triangle of the symmetric matrix A, packed
-C             column-wise. That is, the elements are stored in the order
-C             11, 12, 22, ..., 1n, 2n, 3n, ..., nn,      if UPLO = 'U';
-C             11, 21, 31, ..., n1, 22, 32, ..., n2, ..., if UPLO = 'L'.
-C             On exit, if JOB = 'P', the leading N*(N+1)/2 elements of
-C             this array contain the upper (if UPLO = 'U') or lower
-C             (if UPLO = 'L') triangle of the symmetric matrix A, packed
-C             column-wise, as described above.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Romania,
-C     Oct. 1998.
-C
-C     REVISIONS
-C
-C     -
-C
-C     ******************************************************************
-C
-C     .. Scalar Arguments ..
-      CHARACTER          JOB, UPLO
-      INTEGER            LDA, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA,*), AP(*)
-C     .. Local Scalars ..
-      LOGICAL            LUPLO
-      INTEGER            IJ, J
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DCOPY
-C
-C     .. Executable Statements ..
-C
-C     For efficiency reasons, the parameters are not checked for errors.
-C
-      LUPLO = LSAME( UPLO, 'L' )
-      IJ = 1
-      IF( LSAME( JOB, 'P' ) ) THEN
-         IF( LUPLO ) THEN
-C
-C           Pack the lower triangle of A.
-C
-            DO 20 J = 1, N
-               CALL DCOPY( N-J+1, A(J,J), 1, AP(IJ), 1 )
-               IJ = IJ + N - J + 1
-   20       CONTINUE
-C
-         ELSE
-C
-C           Pack the upper triangle of A.
-C
-            DO 40 J = 1, N
-               CALL DCOPY( J, A(1,J), 1, AP(IJ), 1 )
-               IJ = IJ + J
-   40       CONTINUE
-C
-         END IF
-      ELSE
-         IF( LUPLO ) THEN
-C
-C           Unpack the lower triangle of A.
-C
-            DO 60 J = 1, N
-               CALL DCOPY( N-J+1, AP(IJ), 1, A(J,J), 1 )
-               IJ = IJ + N - J + 1
-   60       CONTINUE
-C
-         ELSE
-C
-C           Unpack the upper triangle of A.
-C
-            DO 80 J = 1, N
-               CALL DCOPY( J, AP(IJ), 1, A(1,J), 1 )
-               IJ = IJ + J
-   80       CONTINUE
-C
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of MA02DD ***
-      END
--- a/extra/control-devel/src/MA02ED.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,99 +0,0 @@
-      SUBROUTINE MA02ED( UPLO, N, A, LDA )
-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 store by symmetry the upper or lower triangle of a symmetric
-C     matrix, given the other triangle.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     UPLO    CHARACTER*1
-C             Specifies which part of the matrix is given as follows:
-C             = 'U':  Upper triangular part;
-C             = 'L':  Lower triangular part.
-C             For all other values, the array A is not referenced.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix A.  N >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, 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 corresponding upper or
-C             lower triangle of the symmetric matrix A.
-C             On exit, the leading N-by-N part of this array contains
-C             the symmetric matrix A with all elements stored.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,N).
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Romania,
-C     Oct. 1998.
-C
-C     REVISIONS
-C
-C     -
-C
-C     ******************************************************************
-C
-C     .. Scalar Arguments ..
-      CHARACTER          UPLO
-      INTEGER            LDA, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA,*)
-C     .. Local Scalars ..
-      INTEGER            J
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DCOPY
-C
-C     .. Executable Statements ..
-C
-C     For efficiency reasons, the parameters are not checked for errors.
-C
-      IF( LSAME( UPLO, 'L' ) ) THEN
-C
-C        Construct the upper triangle of A.
-C
-         DO 20 J = 2, N
-            CALL DCOPY( J-1, A(J,1), LDA, A(1,J), 1 )
-   20    CONTINUE
-C
-      ELSE IF( LSAME( UPLO, 'U' ) ) THEN
-C
-C        Construct the lower triangle of A.
-C
-         DO 40 J = 2, N
-            CALL DCOPY( J-1, A(1,J), 1, A(J,1), LDA )
-   40    CONTINUE
-C
-      END IF
-      RETURN
-C *** Last line of MA02ED ***
-      END
--- a/extra/control-devel/src/MA02FD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,104 +0,0 @@
-      SUBROUTINE MA02FD( X1, X2, C, S, 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 coefficients c and s (c^2 + s^2 = 1) for a modified
-C     hyperbolic plane rotation, such that,
-C
-C         y1 := 1/c * x1 - s/c * x2 = sqrt(x1^2 - x2^2),
-C         y2 :=  -s * y1 +  c  * x2 = 0,
-C
-C     given two real numbers x1 and x2, satisfying either x1 = x2 = 0,
-C     or abs(x2) < abs(x1).
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     X1      (input/output) DOUBLE PRECISION
-C             On entry, the real number x1.
-C             On exit, the real number y1.
-C
-C     X2      (input) DOUBLE PRECISION
-C             The real number x2.
-C             The values x1 and x2 should satisfy either x1 = x2 = 0, or
-C             abs(x2) < abs(x1).
-C
-C     C       (output) DOUBLE PRECISION
-C             The cosines c of the modified hyperbolic plane rotation.
-C
-C     S       (output) DOUBLE PRECISION
-C             The sines s of the modified hyperbolic plane rotation.
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             = 0:  succesful exit;
-C             = 1:  if abs(x2) >= abs(x1) and either x1 <> 0 or x2 <> 0.
-C
-C     CONTRIBUTOR
-C
-C     D. Kressner, Technical Univ. Chemnitz, Germany, June 2000.
-C
-C     REVISIONS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, June 2000.
-C
-C     KEYWORDS
-C
-C     Orthogonal transformation, plane rotation.
-C
-C     *****************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION  X1, X2, C, S
-      INTEGER           INFO
-C     .. Intrinsic Functions ..
-      INTRINSIC         ABS, SIGN, SQRT
-C     .. Executable Statements ..
-C
-      IF ( ( X1.NE.ZERO .OR. X2.NE.ZERO ) .AND.
-     $     ABS( X2 ).GE.ABS( X1 ) ) THEN
-         INFO = 1
-      ELSE
-         INFO = 0
-         IF ( X1.EQ.ZERO ) THEN
-            S = ZERO
-            C = ONE
-         ELSE
-            S = X2 / X1
-C
-C           No overflows could appear in the next statement; underflows
-C           are possible if X2 is tiny and X1 is huge, but then
-C              abs(C) = ONE - delta,
-C           where delta is much less than machine precision.
-C
-            C  = SIGN( SQRT( ONE - S ) * SQRT( ONE + S ), X1 )
-            X1 = C * X1
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of MA02FD ***
-      END
--- a/extra/control-devel/src/MA02GD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,158 +0,0 @@
-      SUBROUTINE MA02GD( N, A, LDA, K1, K2, IPIV, INCX )
-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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To perform a series of column interchanges on the matrix A.
-C     One column interchange is initiated for each of columns K1 through
-C     K2 of A. This is useful for solving linear systems X*A = B, when
-C     the matrix A has already been factored by LAPACK Library routine
-C     DGETRF.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The number of rows of the matrix A.  N >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,*)
-C             On entry, the leading N-by-M part of this array must
-C             contain the matrix A to which the column interchanges will
-C             be applied, where M is the largest element of IPIV(K), for
-C             K = K1, ..., K2.
-C             On exit, the leading N-by-M part of this array contains
-C             the permuted matrix.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= MAX(1,N).
-C
-C     K1      (input) INTEGER
-C             The first element of IPIV for which a column interchange
-C             will be done.
-C
-C     K2      (input) INTEGER
-C             The last element of IPIV for which a column interchange
-C             will be done.
-C
-C     IPIV    (input) INTEGER array, dimension (K1+(K2-K1)*abs(INCX))
-C             The vector of interchanging (pivot) indices.  Only the
-C             elements in positions K1 through K2 of IPIV are accessed.
-C             IPIV(K) = L implies columns K and L are to be
-C             interchanged.
-C
-C     INCX    (input) INTEGER
-C             The increment between successive values of IPIV.
-C             If INCX is negative, the interchanges are applied in
-C             reverse order.
-C
-C     METHOD
-C
-C     The columns IPIV(K) and K are swapped for K = K1, ..., K2, for
-C     INCX = 1 (and similarly, for INCX <> 1).
-C
-C     FURTHER COMMENTS
-C
-C     This routine is the column-oriented counterpart of the LAPACK
-C     Library routine DLASWP. The LAPACK Library routine DLAPMT cannot
-C     be used in this context. To solve the system X*A = B, where A and
-C     B are N-by-N and M-by-N, respectively, the following statements
-C     can be used:
-C
-C         CALL DGETRF( N, N, A, LDA, IPIV, INFO )
-C         CALL DTRSM( 'R', 'U', 'N', 'N', M, N, ONE, A, LDA, B, LDB )
-C         CALL DTRSM( 'R', 'L', 'N', 'U', M, N, ONE, A, LDA, B, LDB )
-C         CALL MA02GD( M, B, LDB, 1, N, IPIV, -1 )
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Mar. 2000.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 2008.
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, linear algebra.
-C
-C    ******************************************************************
-C
-C      .. Scalar Arguments ..
-      INTEGER            INCX, K1, K2, LDA, N
-C      ..
-C      .. Array Arguments ..
-      INTEGER            IPIV( * )
-      DOUBLE PRECISION   A( LDA, * )
-C     ..
-C     .. Local Scalars ..
-      INTEGER            J, JP, JX
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DSWAP
-C     ..
-C     .. Executable Statements ..
-C
-C     Quick return if possible.
-C
-      IF( INCX.EQ.0 .OR. N.EQ.0 )
-     $   RETURN
-C
-C     Interchange column J with column IPIV(J) for each of columns K1
-C     through K2.
-C
-      IF( INCX.GT.0 ) THEN
-         JX = K1
-      ELSE
-         JX = 1 + ( 1-K2 )*INCX
-      END IF
-C
-      IF( INCX.EQ.1 ) THEN
-C
-         DO 10 J = K1, K2
-            JP = IPIV( J )
-            IF( JP.NE.J )
-     $         CALL DSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 )
-   10    CONTINUE
-C
-      ELSE IF( INCX.GT.1 ) THEN
-C
-         DO 20 J = K1, K2
-            JP = IPIV( JX )
-            IF( JP.NE.J )
-     $         CALL DSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 )
-            JX = JX + INCX
-   20    CONTINUE
-C
-      ELSE IF( INCX.LT.0 ) THEN
-C
-         DO 30 J = K2, K1, -1
-            JP = IPIV( JX )
-            IF( JP.NE.J )
-     $         CALL DSWAP( N, A( 1, J ), 1, A( 1, JP ), 1 )
-            JX = JX + INCX
-   30    CONTINUE
-C
-      END IF
-C
-      RETURN
-C
-C *** Last line of MA02GD ***
-      END
--- a/extra/control-devel/src/MB01PD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,271 +0,0 @@
-      SUBROUTINE MB01PD( SCUN, TYPE, M, N, KL, KU, ANRM, NBL, NROWS, A,
-     $                   LDA, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To scale a matrix or undo scaling.  Scaling is performed, if
-C     necessary, so that the matrix norm will be in a safe range of
-C     representable numbers.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     SCUN    CHARACTER*1
-C             SCUN indicates the operation to be performed.
-C             = 'S':  scale the matrix.
-C             = 'U':  undo scaling of the matrix.
-C
-C     TYPE    CHARACTER*1
-C             TYPE indicates the storage type of the input matrix.
-C             = 'G':  A is a full matrix.
-C             = 'L':  A is a (block) lower triangular matrix.
-C             = 'U':  A is an (block) upper triangular matrix.
-C             = 'H':  A is an (block) upper Hessenberg matrix.
-C             = 'B':  A is a symmetric band matrix with lower bandwidth
-C                     KL and upper bandwidth KU and with the only the
-C                     lower half stored.
-C             = 'Q':  A is a symmetric band matrix with lower bandwidth
-C                     KL and upper bandwidth KU and with the only the
-C                     upper half stored.
-C             = 'Z':  A is a band matrix with lower bandwidth KL and
-C                     upper bandwidth KU.
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrix A. M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrix A. N >= 0.
-C
-C     KL      (input) INTEGER
-C             The lower bandwidth of A.  Referenced only if TYPE = 'B',
-C             'Q' or 'Z'.
-C
-C     KU      (input) INTEGER
-C             The upper bandwidth of A.  Referenced only if TYPE = 'B',
-C             'Q' or 'Z'.
-C
-C     ANRM    (input) DOUBLE PRECISION
-C             The norm of the initial matrix A.  ANRM >= 0.
-C             When  ANRM = 0  then an immediate return is effected.
-C             ANRM should be preserved between the call of the routine
-C             with SCUN = 'S' and the corresponding one with SCUN = 'U'.
-C
-C     NBL     (input) INTEGER
-C             The number of diagonal blocks of the matrix A, if it has a
-C             block structure.  To specify that matrix A has no block
-C             structure, set NBL = 0.  NBL >= 0.
-C
-C     NROWS   (input) INTEGER array, dimension max(1,NBL)
-C             NROWS(i) contains the number of rows and columns of the
-C             i-th diagonal block of matrix A.  The sum of the values
-C             NROWS(i),  for  i = 1: NBL,  should be equal to min(M,N).
-C             The elements of the array  NROWS  are not referenced if
-C             NBL = 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading M by N part of this array must
-C             contain the matrix to be scaled/unscaled.
-C             On exit, the leading M by N part of A will contain
-C             the modified matrix.
-C             The storage mode of A is specified by TYPE.
-C
-C     LDA     (input) INTEGER
-C             The leading dimension of the array A.  LDA  >= max(1,M).
-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
-C     METHOD
-C
-C     Denote by ANRM the norm of the matrix, and by SMLNUM and BIGNUM,
-C     two positive numbers near the smallest and largest safely
-C     representable numbers, respectively.  The matrix is scaled, if
-C     needed, such that the norm of the result is in the range
-C     [SMLNUM, BIGNUM].  The scaling factor is represented as a ratio
-C     of two numbers, one of them being ANRM, and the other one either
-C     SMLNUM or BIGNUM, depending on ANRM being less than SMLNUM or
-C     larger than BIGNUM, respectively.  For undoing the scaling, the
-C     norm is again compared with SMLNUM or BIGNUM, and the reciprocal
-C     of the previous scaling factor is used.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Nov. 1996.
-C
-C     REVISIONS
-C
-C     Oct. 2001, V. Sima, Research Institute for Informatics, Bucharest.
-C
-C    ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER          SCUN, TYPE
-      INTEGER            INFO, KL, KU, LDA, M, MN, N, NBL
-      DOUBLE PRECISION   ANRM
-C     .. Array Arguments ..
-      INTEGER            NROWS ( * )
-      DOUBLE PRECISION   A( LDA, * )
-C     .. Local Scalars ..
-      LOGICAL            FIRST, LSCALE
-      INTEGER            I, ISUM, ITYPE
-      DOUBLE PRECISION   BIGNUM, SMLNUM
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           DLAMCH, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DLABAD, MB01QD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX, MIN
-C     .. Save statement ..
-      SAVE               BIGNUM, FIRST, SMLNUM
-C     .. Data statements ..
-      DATA               FIRST/.TRUE./
-C     ..
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO = 0
-      LSCALE = LSAME( SCUN, 'S' )
-      IF( LSAME( TYPE, 'G' ) ) THEN
-         ITYPE = 0
-      ELSE IF( LSAME( TYPE, 'L' ) ) THEN
-         ITYPE = 1
-      ELSE IF( LSAME( TYPE, 'U' ) ) THEN
-         ITYPE = 2
-      ELSE IF( LSAME( TYPE, 'H' ) ) THEN
-         ITYPE = 3
-      ELSE IF( LSAME( TYPE, 'B' ) ) THEN
-         ITYPE = 4
-      ELSE IF( LSAME( TYPE, 'Q' ) ) THEN
-         ITYPE = 5
-      ELSE IF( LSAME( TYPE, 'Z' ) ) THEN
-         ITYPE = 6
-      ELSE
-         ITYPE = -1
-      END IF
-C
-      MN = MIN( M, N )
-C
-      ISUM = 0
-      IF( NBL.GT.0 ) THEN
-         DO 10 I = 1, NBL
-            ISUM = ISUM + NROWS(I)
- 10      CONTINUE
-      END IF
-C
-      IF( .NOT.LSCALE .AND. .NOT.LSAME( SCUN, 'U' ) ) THEN
-         INFO = -1
-      ELSE IF( ITYPE.EQ.-1 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 .OR.
-     $         ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. N.NE.M ) ) THEN
-         INFO = -4
-      ELSE IF( ANRM.LT.ZERO ) THEN
-         INFO = -7
-      ELSE IF( NBL.LT.0 ) THEN
-         INFO = -8
-      ELSE IF( NBL.GT.0 .AND. ISUM.NE.MN ) THEN
-         INFO = -9
-      ELSE IF( ITYPE.LE.3 .AND. LDA.LT.MAX( 1, M ) ) THEN
-         INFO = -11
-      ELSE IF( ITYPE.GE.4 ) THEN
-         IF( KL.LT.0 .OR. KL.GT.MAX( M-1, 0 ) ) THEN
-            INFO = -5
-         ELSE IF( KU.LT.0 .OR. KU.GT.MAX( N-1, 0 ) .OR.
-     $            ( ( ITYPE.EQ.4 .OR. ITYPE.EQ.5 ) .AND. KL.NE.KU ) )
-     $             THEN
-            INFO = -6
-         ELSE IF( ( ITYPE.EQ.4 .AND. LDA.LT.KL+1 ) .OR.
-     $            ( ITYPE.EQ.5 .AND. LDA.LT.KU+1 ) .OR.
-     $            ( ITYPE.EQ.6 .AND. LDA.LT.2*KL+KU+1 ) ) THEN
-            INFO = -11
-         END IF
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'MB01PD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MN.EQ.0 .OR. ANRM.EQ.ZERO )
-     $   RETURN
-C
-      IF ( FIRST ) THEN
-C
-C        Get machine parameters.
-C
-         SMLNUM = DLAMCH( 'S' ) / DLAMCH( 'P' )
-         BIGNUM = ONE / SMLNUM
-         CALL DLABAD( SMLNUM, BIGNUM )
-         FIRST = .FALSE.
-      END IF
-C
-      IF ( LSCALE ) THEN
-C
-C        Scale A, if its norm is outside range [SMLNUM,BIGNUM].
-C
-         IF( ANRM.LT.SMLNUM ) THEN
-C
-C           Scale matrix norm up to SMLNUM.
-C
-            CALL MB01QD( TYPE, M, N, KL, KU, ANRM, SMLNUM, NBL, NROWS,
-     $                   A, LDA, INFO )
-         ELSE IF( ANRM.GT.BIGNUM ) THEN
-C
-C           Scale matrix norm down to BIGNUM.
-C
-            CALL MB01QD( TYPE, M, N, KL, KU, ANRM, BIGNUM, NBL, NROWS,
-     $                   A, LDA, INFO )
-         END IF
-C
-      ELSE
-C
-C        Undo scaling.
-C
-         IF( ANRM.LT.SMLNUM ) THEN
-            CALL MB01QD( TYPE, M, N, KL, KU, SMLNUM, ANRM, NBL, NROWS,
-     $                   A, LDA, INFO )
-         ELSE IF( ANRM.GT.BIGNUM ) THEN
-            CALL MB01QD( TYPE, M, N, KL, KU, BIGNUM, ANRM, NBL, NROWS,
-     $                   A, LDA, INFO )
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of MB01PD ***
-      END
--- a/extra/control-devel/src/MB01QD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,334 +0,0 @@
-      SUBROUTINE MB01QD( TYPE, M, N, KL, KU, CFROM, CTO, NBL, NROWS, A,
-     $                   LDA, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To multiply the M by N real matrix A by the real scalar CTO/CFROM.
-C     This is done without over/underflow as long as the final result
-C     CTO*A(I,J)/CFROM does not over/underflow. TYPE specifies that
-C     A may be full, (block) upper triangular, (block) lower triangular,
-C     (block) upper Hessenberg, or banded.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     TYPE    CHARACTER*1
-C             TYPE indices the storage type of the input matrix.
-C             = 'G':  A is a full matrix.
-C             = 'L':  A is a (block) lower triangular matrix.
-C             = 'U':  A is a (block) upper triangular matrix.
-C             = 'H':  A is a (block) upper Hessenberg matrix.
-C             = 'B':  A is a symmetric band matrix with lower bandwidth
-C                     KL and upper bandwidth KU and with the only the
-C                     lower half stored.
-C             = 'Q':  A is a symmetric band matrix with lower bandwidth
-C                     KL and upper bandwidth KU and with the only the
-C                     upper half stored.
-C             = 'Z':  A is a band matrix with lower bandwidth KL and
-C                     upper bandwidth KU.
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrix A.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrix A.  N >= 0.
-C
-C     KL      (input) INTEGER
-C             The lower bandwidth of A.  Referenced only if TYPE = 'B',
-C             'Q' or 'Z'.
-C
-C     KU      (input) INTEGER
-C             The upper bandwidth of A.  Referenced only if TYPE = 'B',
-C             'Q' or 'Z'.
-C
-C     CFROM   (input) DOUBLE PRECISION
-C     CTO     (input) DOUBLE PRECISION
-C             The matrix A is multiplied by CTO/CFROM. A(I,J) is
-C             computed without over/underflow if the final result
-C             CTO*A(I,J)/CFROM can be represented without over/
-C             underflow.  CFROM must be nonzero.
-C
-C     NBL     (input) INTEGER
-C             The number of diagonal blocks of the matrix A, if it has a
-C             block structure.  To specify that matrix A has no block
-C             structure, set NBL = 0.  NBL >= 0.
-C
-C     NROWS   (input) INTEGER array, dimension max(1,NBL)
-C             NROWS(i) contains the number of rows and columns of the
-C             i-th diagonal block of matrix A.  The sum of the values
-C             NROWS(i),  for  i = 1: NBL,  should be equal to min(M,N).
-C             The array  NROWS  is not referenced if NBL = 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             The matrix to be multiplied by CTO/CFROM.  See TYPE for
-C             the storage type.
-C
-C     LDA     (input) INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,M).
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             Not used in this implementation.
-C
-C     METHOD
-C
-C     Matrix A is multiplied by the real scalar CTO/CFROM, taking into
-C     account the specified storage mode of the matrix.
-C     MB01QD is a version of the LAPACK routine DLASCL, modified for
-C     dealing with block triangular, or block Hessenberg matrices.
-C     For efficiency, no tests of the input scalar parameters are
-C     performed.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Nov. 1996.
-C
-C    ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          TYPE
-      INTEGER            INFO, KL, KU, LDA, M, N, NBL
-      DOUBLE PRECISION   CFROM, CTO
-C     ..
-C     .. Array Arguments ..
-      INTEGER            NROWS ( * )
-      DOUBLE PRECISION   A( LDA, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            DONE, NOBLC
-      INTEGER            I, IFIN, ITYPE, J, JFIN, JINI, K, K1, K2, K3,
-     $                   K4
-      DOUBLE PRECISION   BIGNUM, CFROM1, CFROMC, CTO1, CTOC, MUL, SMLNUM
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           LSAME, DLAMCH
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-      IF( LSAME( TYPE, 'G' ) ) THEN
-         ITYPE = 0
-      ELSE IF( LSAME( TYPE, 'L' ) ) THEN
-         ITYPE = 1
-      ELSE IF( LSAME( TYPE, 'U' ) ) THEN
-         ITYPE = 2
-      ELSE IF( LSAME( TYPE, 'H' ) ) THEN
-         ITYPE = 3
-      ELSE IF( LSAME( TYPE, 'B' ) ) THEN
-         ITYPE = 4
-      ELSE IF( LSAME( TYPE, 'Q' ) ) THEN
-         ITYPE = 5
-      ELSE
-         ITYPE = 6
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( M, N ).EQ.0 )
-     $   RETURN
-C
-C     Get machine parameters.
-C
-      SMLNUM = DLAMCH( 'S' )
-      BIGNUM = ONE / SMLNUM
-C
-      CFROMC = CFROM
-      CTOC = CTO
-C
-   10 CONTINUE
-      CFROM1 = CFROMC*SMLNUM
-      CTO1 = CTOC / BIGNUM
-      IF( ABS( CFROM1 ).GT.ABS( CTOC ) .AND. CTOC.NE.ZERO ) THEN
-         MUL = SMLNUM
-         DONE = .FALSE.
-         CFROMC = CFROM1
-      ELSE IF( ABS( CTO1 ).GT.ABS( CFROMC ) ) THEN
-         MUL = BIGNUM
-         DONE = .FALSE.
-         CTOC = CTO1
-      ELSE
-         MUL = CTOC / CFROMC
-         DONE = .TRUE.
-      END IF
-C
-      NOBLC = NBL.EQ.0
-C
-      IF( ITYPE.EQ.0 ) THEN
-C
-C        Full matrix
-C
-         DO 30 J = 1, N
-            DO 20 I = 1, M
-               A( I, J ) = A( I, J )*MUL
-   20       CONTINUE
-   30    CONTINUE
-C
-      ELSE IF( ITYPE.EQ.1 ) THEN
-C
-         IF ( NOBLC ) THEN
-C
-C           Lower triangular matrix
-C
-            DO 50 J = 1, N
-               DO 40 I = J, M
-                  A( I, J ) = A( I, J )*MUL
-   40          CONTINUE
-   50       CONTINUE
-C
-         ELSE
-C
-C           Block lower triangular matrix
-C
-            JFIN = 0
-            DO 80 K = 1, NBL
-               JINI = JFIN + 1
-               JFIN = JFIN + NROWS( K )
-               DO 70 J = JINI, JFIN
-                  DO 60 I = JINI, M
-                     A( I, J ) = A( I, J )*MUL
-   60             CONTINUE
-   70          CONTINUE
-   80       CONTINUE
-         END IF
-C
-      ELSE IF( ITYPE.EQ.2 ) THEN
-C
-         IF ( NOBLC ) THEN
-C
-C           Upper triangular matrix
-C
-            DO 100 J = 1, N
-               DO 90 I = 1, MIN( J, M )
-                  A( I, J ) = A( I, J )*MUL
-   90          CONTINUE
-  100       CONTINUE
-C
-         ELSE
-C
-C           Block upper triangular matrix
-C
-            JFIN = 0
-            DO 130 K = 1, NBL
-               JINI = JFIN + 1
-               JFIN = JFIN + NROWS( K )
-               IF ( K.EQ.NBL ) JFIN = N
-               DO 120 J = JINI, JFIN
-                  DO 110 I = 1, MIN( JFIN, M )
-                     A( I, J ) = A( I, J )*MUL
-  110             CONTINUE
-  120          CONTINUE
-  130       CONTINUE
-         END IF
-C
-      ELSE IF( ITYPE.EQ.3 ) THEN
-C
-         IF ( NOBLC ) THEN
-C
-C           Upper Hessenberg matrix
-C
-            DO 150 J = 1, N
-               DO 140 I = 1, MIN( J+1, M )
-                  A( I, J ) = A( I, J )*MUL
-  140          CONTINUE
-  150       CONTINUE
-C
-         ELSE
-C
-C           Block upper Hessenberg matrix
-C
-            JFIN = 0
-            DO 180 K = 1, NBL
-               JINI = JFIN + 1
-               JFIN = JFIN + NROWS( K )
-C
-               IF ( K.EQ.NBL ) THEN
-                  JFIN = N
-                  IFIN = N
-               ELSE
-                  IFIN = JFIN + NROWS( K+1 )
-               END IF
-C
-               DO 170 J = JINI, JFIN
-                  DO 160 I = 1, MIN( IFIN, M )
-                     A( I, J ) = A( I, J )*MUL
-  160             CONTINUE
-  170          CONTINUE
-  180       CONTINUE
-         END IF
-C
-      ELSE IF( ITYPE.EQ.4 ) THEN
-C
-C        Lower half of a symmetric band matrix
-C
-         K3 = KL + 1
-         K4 = N + 1
-         DO 200 J = 1, N
-            DO 190 I = 1, MIN( K3, K4-J )
-               A( I, J ) = A( I, J )*MUL
-  190       CONTINUE
-  200    CONTINUE
-C
-      ELSE IF( ITYPE.EQ.5 ) THEN
-C
-C        Upper half of a symmetric band matrix
-C
-         K1 = KU + 2
-         K3 = KU + 1
-         DO 220 J = 1, N
-            DO 210 I = MAX( K1-J, 1 ), K3
-               A( I, J ) = A( I, J )*MUL
-  210       CONTINUE
-  220    CONTINUE
-C
-      ELSE IF( ITYPE.EQ.6 ) THEN
-C
-C        Band matrix
-C
-         K1 = KL + KU + 2
-         K2 = KL + 1
-         K3 = 2*KL + KU + 1
-         K4 = KL + KU + 1 + M
-         DO 240 J = 1, N
-            DO 230 I = MAX( K1-J, K2 ), MIN( K3, K4-J )
-               A( I, J ) = A( I, J )*MUL
-  230       CONTINUE
-  240    CONTINUE
-C
-      END IF
-C
-      IF( .NOT.DONE )
-     $   GO TO 10
-C
-      RETURN
-C *** Last line of MB01QD ***
-      END
--- a/extra/control-devel/src/MB01RU.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,282 +0,0 @@
-      SUBROUTINE MB01RU( UPLO, TRANS, M, N, ALPHA, BETA, R, LDR, A, LDA,
-     $                   X, LDX, 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 compute the matrix formula
-C        _
-C        R = alpha*R + beta*op( A )*X*op( A )',
-C                                                 _
-C     where alpha and beta are scalars, R, X, and R are symmetric
-C     matrices, A is a general matrix, and op( A ) is one of
-C
-C        op( A ) = A   or   op( A ) = A'.
-C
-C     The result is overwritten on R.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     UPLO    CHARACTER*1
-C             Specifies which triangles of the symmetric matrices R
-C             and X are given as follows:
-C             = 'U':  the upper triangular part is given;
-C             = 'L':  the lower triangular part is given.
-C
-C     TRANS   CHARACTER*1
-C             Specifies the form of op( A ) to be used in the matrix
-C             multiplication as follows:
-C             = 'N':  op( A ) = A;
-C             = 'T':  op( A ) = A';
-C             = 'C':  op( A ) = A'.
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER           _
-C             The order of the matrices R and R and the number of rows
-C             of the matrix op( A ).  M >= 0.
-C
-C     N       (input) INTEGER
-C             The order of the matrix X and the number of columns of the
-C             the matrix op( A ).  N >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The scalar alpha. When alpha is zero then R need not be
-C             set before entry, except when R is identified with X in
-C             the call.
-C
-C     BETA    (input) DOUBLE PRECISION
-C             The scalar beta. When beta is zero then A and X are not
-C             referenced.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,M)
-C             On entry with UPLO = 'U', the leading M-by-M upper
-C             triangular part of this array must contain the upper
-C             triangular part of the symmetric matrix R.
-C             On entry with UPLO = 'L', the leading M-by-M lower
-C             triangular part of this array must contain the lower
-C             triangular part of the symmetric matrix R.
-C             On exit, the leading M-by-M upper triangular part (if
-C             UPLO = 'U'), or lower triangular part (if UPLO = 'L'), of
-C             this array contains the corresponding triangular part of
-C                                 _
-C             the computed matrix R.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,M).
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,k)
-C             where k is N when TRANS = 'N' and is M when TRANS = 'T' or
-C             TRANS = 'C'.
-C             On entry with TRANS = 'N', the leading M-by-N part of this
-C             array must contain the matrix A.
-C             On entry with TRANS = 'T' or TRANS = 'C', the leading
-C             N-by-M part of this array must contain the matrix A.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,k),
-C             where k is M when TRANS = 'N' and is N when TRANS = 'T' or
-C             TRANS = 'C'.
-C
-C     X       (input) DOUBLE PRECISION array, dimension (LDX,N)
-C             On entry, if UPLO = 'U', the leading N-by-N upper
-C             triangular part of this array must contain the upper
-C             triangular part of the symmetric matrix X and the strictly
-C             lower triangular part of the array is not referenced.
-C             On entry, if UPLO = 'L', the leading N-by-N lower
-C             triangular part of this array must contain the lower
-C             triangular part of the symmetric matrix X and the strictly
-C             upper triangular part of the array is not referenced.
-C             The diagonal elements of this array are modified
-C             internally, but are restored on exit.
-C
-C     LDX     INTEGER
-C             The leading dimension of array X.  LDX >= MAX(1,N).
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             This array is not referenced when beta = 0, or M*N = 0.
-C
-C     LDWORK  The length of the array DWORK.
-C             LDWORK >= M*N, if  beta <> 0;
-C             LDWORK >= 0,   if  beta =  0.
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             = 0:  successful exit;
-C             < 0:  if INFO = -k, the k-th argument had an illegal
-C                   value.
-C
-C     METHOD
-C
-C     The matrix expression is efficiently evaluated taking the symmetry
-C     into account. Specifically, let X = T + T', with T an upper or
-C     lower triangular matrix, defined by
-C
-C        T = triu( X ) - (1/2)*diag( X ),  if UPLO = 'U',
-C        T = tril( X ) - (1/2)*diag( X ),  if UPLO = 'L',
-C
-C     where triu, tril, and diag denote the upper triangular part, lower
-C     triangular part, and diagonal part of X, respectively. Then,
-C
-C        A*X*A' = ( A*T )*A' + A*( A*T )',  for TRANS = 'N',
-C        A'*X*A = A'*( T*A ) + ( T*A )'*A,  for TRANS = 'T', or 'C',
-C
-C     which involve BLAS 3 operations (DTRMM and DSYR2K).
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm requires approximately
-C
-C                   2         2
-C        3/2 x M x N + 1/2 x M
-C
-C     operations.
-C
-C     FURTHER COMMENTS
-C
-C     This is a simpler version for MB01RD.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Jan. 1999.
-C
-C     REVISIONS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, March 2004.
-C     V. Sima, Research Institute for Informatics, Bucharest, Mar. 2004.
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, matrix algebra, matrix operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE, TWO, HALF
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
-     $                  HALF = 0.5D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         TRANS, UPLO
-      INTEGER           INFO, LDA, LDR, LDWORK, LDX, M, N
-      DOUBLE PRECISION  ALPHA, BETA
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), DWORK(*), R(LDR,*), X(LDX,*)
-C     .. Local Scalars ..
-      LOGICAL           LTRANS, LUPLO
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DLACPY, DLASCL, DLASET, DSCAL, DSYR2K, DTRMM,
-     $                  XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO = 0
-      LUPLO  = LSAME( UPLO,  'U' )
-      LTRANS = LSAME( TRANS, 'T' ) .OR. LSAME( TRANS, 'C' )
-C
-      IF(      ( .NOT.LUPLO  ).AND.( .NOT.LSAME( UPLO,  'L' ) ) )THEN
-         INFO = -1
-      ELSE IF( ( .NOT.LTRANS ).AND.( .NOT.LSAME( TRANS, 'N' ) ) )THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDR.LT.MAX( 1, M ) ) THEN
-         INFO = -8
-      ELSE IF( LDA.LT.1 .OR. ( LTRANS .AND. LDA.LT.N ) .OR.
-     $                  ( .NOT.LTRANS .AND. LDA.LT.M ) ) THEN
-         INFO = -10
-      ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
-         INFO = -12
-      ELSE IF( ( BETA.NE.ZERO .AND. LDWORK.LT.M*N )
-     $     .OR.( BETA.EQ.ZERO .AND. LDWORK.LT.0 ) ) THEN
-         INFO = -14
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB01RU', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( M.EQ.0 )
-     $   RETURN
-C
-      IF ( BETA.EQ.ZERO .OR. N.EQ.0 ) THEN
-         IF ( ALPHA.EQ.ZERO ) THEN
-C
-C           Special case alpha = 0.
-C
-            CALL DLASET( UPLO, M, M, ZERO, ZERO, R, LDR )
-         ELSE
-C
-C           Special case beta = 0 or N = 0.
-C
-            IF ( ALPHA.NE.ONE )
-     $         CALL DLASCL( UPLO, 0, 0, ONE, ALPHA, M, M, R, LDR, INFO )
-         END IF
-         RETURN
-      END IF
-C
-C     General case: beta <> 0.
-C     Compute W = op( A )*T or W = T*op( A ) in DWORK, and apply the
-C     updating formula (see METHOD section).
-C     Workspace: need M*N.
-C
-      CALL DSCAL( N, HALF, X, LDX+1 )
-C
-      IF( LTRANS ) THEN
-C
-         CALL DLACPY( 'Full', N, M, A, LDA, DWORK, N )
-         CALL DTRMM(  'Left', UPLO, 'NoTranspose', 'Non-unit', N, M,
-     $                ONE, X, LDX, DWORK, N )
-         CALL DSYR2K( UPLO, TRANS, M, N, BETA, DWORK, N, A, LDA, ALPHA,
-     $                R, LDR )
-C
-      ELSE
-C
-         CALL DLACPY( 'Full', M, N, A, LDA, DWORK, M )
-         CALL DTRMM(  'Right', UPLO, 'NoTranspose', 'Non-unit', M, N,
-     $                ONE, X, LDX, DWORK, M )
-         CALL DSYR2K( UPLO, TRANS, M, N, BETA, DWORK, M, A, LDA, ALPHA,
-     $                R, LDR )
-C
-      END IF
-C
-      CALL DSCAL( N, TWO, X, LDX+1 )
-C
-      RETURN
-C *** Last line of MB01RU ***
-      END
--- a/extra/control-devel/src/MB01RX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,315 +0,0 @@
-      SUBROUTINE MB01RX( SIDE, UPLO, TRANS, M, N, ALPHA, BETA, R, LDR,
-     $                   A, LDA, B, LDB, 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 either the upper or lower triangular part of one of the
-C     matrix formulas
-C        _
-C        R = alpha*R + beta*op( A )*B,                               (1)
-C        _
-C        R = alpha*R + beta*B*op( A ),                               (2)
-C                                             _
-C     where alpha and beta are scalars, R and R are m-by-m matrices,
-C     op( A ) and B are m-by-n and n-by-m matrices for (1), or n-by-m
-C     and m-by-n matrices for (2), respectively, and op( A ) is one of
-C
-C        op( A ) = A   or   op( A ) = A',  the transpose of A.
-C
-C     The result is overwritten on R.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     SIDE    CHARACTER*1
-C             Specifies whether the matrix A appears on the left or
-C             right in the matrix product as follows:
-C                     _
-C             = 'L':  R = alpha*R + beta*op( A )*B;
-C                     _
-C             = 'R':  R = alpha*R + beta*B*op( A ).
-C
-C     UPLO    CHARACTER*1                               _
-C             Specifies which triangles of the matrices R and R are
-C             computed and given, respectively, as follows:
-C             = 'U':  the upper triangular part;
-C             = 'L':  the lower triangular part.
-C
-C     TRANS   CHARACTER*1
-C             Specifies the form of op( A ) to be used in the matrix
-C             multiplication as follows:
-C             = 'N':  op( A ) = A;
-C             = 'T':  op( A ) = A';
-C             = 'C':  op( A ) = A'.
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER           _
-C             The order of the matrices R and R, the number of rows of
-C             the matrix op( A ) and the number of columns of the
-C             matrix B, for SIDE = 'L', or the number of rows of the
-C             matrix B and the number of columns of the matrix op( A ),
-C             for SIDE = 'R'.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of rows of the matrix B and the number of
-C             columns of the matrix op( A ), for SIDE = 'L', or the
-C             number of rows of the matrix op( A ) and the number of
-C             columns of the matrix B, for SIDE = 'R'.  N >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The scalar alpha. When alpha is zero then R need not be
-C             set before entry.
-C
-C     BETA    (input) DOUBLE PRECISION
-C             The scalar beta. When beta is zero then A and B are not
-C             referenced.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,M)
-C             On entry with UPLO = 'U', the leading M-by-M upper
-C             triangular part of this array must contain the upper
-C             triangular part of the matrix R; the strictly lower
-C             triangular part of the array is not referenced.
-C             On entry with UPLO = 'L', the leading M-by-M lower
-C             triangular part of this array must contain the lower
-C             triangular part of the matrix R; the strictly upper
-C             triangular part of the array is not referenced.
-C             On exit, the leading M-by-M upper triangular part (if
-C             UPLO = 'U'), or lower triangular part (if UPLO = 'L') of
-C             this array contains the corresponding triangular part of
-C                                 _
-C             the computed matrix R.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,M).
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,k), where
-C             k = N  when  SIDE = 'L', and TRANS = 'N', or
-C                          SIDE = 'R', and TRANS = 'T';
-C             k = M  when  SIDE = 'R', and TRANS = 'N', or
-C                          SIDE = 'L', and TRANS = 'T'.
-C             On entry, if SIDE = 'L', and TRANS = 'N', or
-C                          SIDE = 'R', and TRANS = 'T',
-C             the leading M-by-N part of this array must contain the
-C             matrix A.
-C             On entry, if SIDE = 'R', and TRANS = 'N', or
-C                          SIDE = 'L', and TRANS = 'T',
-C             the leading N-by-M part of this array must contain the
-C             matrix A.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,l), where
-C             l = M  when  SIDE = 'L', and TRANS = 'N', or
-C                          SIDE = 'R', and TRANS = 'T';
-C             l = N  when  SIDE = 'R', and TRANS = 'N', or
-C                          SIDE = 'L', and TRANS = 'T'.
-C
-C     B       (input) DOUBLE PRECISION array, dimension (LDB,p), where
-C             p = M  when  SIDE = 'L';
-C             p = N  when  SIDE = 'R'.
-C             On entry, the leading N-by-M part, if SIDE = 'L', or
-C             M-by-N part, if SIDE = 'R', of this array must contain the
-C             matrix B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.
-C             LDB >= MAX(1,N), if SIDE = 'L';
-C             LDB >= MAX(1,M), if SIDE = 'R'.
-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     METHOD
-C
-C     The matrix expression is evaluated taking the triangular
-C     structure into account. BLAS 2 operations are used. A block
-C     algorithm can be easily constructed; it can use BLAS 3 GEMM
-C     operations for most computations, and calls of this BLAS 2
-C     algorithm for computing the triangles.
-C
-C     FURTHER COMMENTS
-C
-C     The main application of this routine is when the result should
-C     be a symmetric matrix, e.g., when B = X*op( A )', for (1), or
-C     B = op( A )'*X, for (2), where B is already available and X = X'.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1999.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Mar. 2004.
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, matrix algebra, matrix operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         SIDE, TRANS, UPLO
-      INTEGER           INFO, LDA, LDB, LDR, M, N
-      DOUBLE PRECISION  ALPHA, BETA
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), R(LDR,*)
-C     .. Local Scalars ..
-      LOGICAL           LSIDE, LTRANS, LUPLO
-      INTEGER           J
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DGEMV, DLASCL, DLASET, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO   = 0
-      LSIDE  = LSAME( SIDE,  'L' )
-      LUPLO  = LSAME( UPLO,  'U' )
-      LTRANS = LSAME( TRANS, 'T' ) .OR. LSAME( TRANS, 'C' )
-C
-      IF(      ( .NOT.LSIDE  ).AND.( .NOT.LSAME( SIDE,  'R' ) ) )THEN
-         INFO = -1
-      ELSE IF( ( .NOT.LUPLO  ).AND.( .NOT.LSAME( UPLO,  'L' ) ) )THEN
-         INFO = -2
-      ELSE IF( ( .NOT.LTRANS ).AND.( .NOT.LSAME( TRANS, 'N' ) ) )THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( LDR.LT.MAX( 1, M ) ) THEN
-         INFO = -9
-      ELSE IF( LDA.LT.1 .OR.
-     $   ( ( (      LSIDE .AND. .NOT.LTRANS ) .OR.
-     $       ( .NOT.LSIDE .AND.      LTRANS ) ) .AND. LDA.LT.M ) .OR.
-     $   ( ( (      LSIDE .AND.      LTRANS ) .OR.
-     $       ( .NOT.LSIDE .AND. .NOT.LTRANS ) ) .AND. LDA.LT.N ) ) THEN
-         INFO = -11
-      ELSE IF( LDB.LT.1 .OR.
-     $       (      LSIDE .AND. LDB.LT.N ) .OR.
-     $       ( .NOT.LSIDE .AND. LDB.LT.M ) ) THEN
-         INFO = -13
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB01RX', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( M.EQ.0 )
-     $   RETURN
-C
-      IF ( BETA.EQ.ZERO .OR. N.EQ.0 ) THEN
-         IF ( ALPHA.EQ.ZERO ) THEN
-C
-C           Special case alpha = 0.
-C
-            CALL DLASET( UPLO, M, M, ZERO, ZERO, R, LDR )
-         ELSE
-C
-C           Special case beta = 0 or N = 0.
-C
-            IF ( ALPHA.NE.ONE )
-     $         CALL DLASCL( UPLO, 0, 0, ONE, ALPHA, M, M, R, LDR, INFO )
-         END IF
-         RETURN
-      END IF
-C
-C     General case: beta <> 0.
-C     Compute the required triangle of (1) or (2) using BLAS 2
-C     operations.
-C
-      IF( LSIDE ) THEN
-         IF( LUPLO ) THEN
-            IF ( LTRANS ) THEN
-               DO 10 J = 1, M
-                  CALL DGEMV( TRANS, N, J, BETA, A, LDA, B(1,J), 1,
-     $                        ALPHA, R(1,J), 1 )
-   10          CONTINUE
-            ELSE
-               DO 20 J = 1, M
-                  CALL DGEMV( TRANS, J, N, BETA, A, LDA, B(1,J), 1,
-     $                        ALPHA, R(1,J), 1 )
-   20          CONTINUE
-            END IF
-         ELSE
-            IF ( LTRANS ) THEN
-               DO 30 J = 1, M
-                  CALL DGEMV( TRANS, N, M-J+1, BETA, A(1,J), LDA,
-     $                        B(1,J), 1, ALPHA, R(J,J), 1 )
-   30          CONTINUE
-            ELSE
-               DO 40 J = 1, M
-                  CALL DGEMV( TRANS, M-J+1, N, BETA, A(J,1), LDA,
-     $                        B(1,J), 1, ALPHA, R(J,J), 1 )
-   40          CONTINUE
-            END IF
-         END IF
-C
-      ELSE
-         IF( LUPLO ) THEN
-            IF( LTRANS ) THEN
-               DO 50 J = 1, M
-                  CALL DGEMV( 'NoTranspose', J, N, BETA, B, LDB, A(J,1),
-     $                        LDA, ALPHA, R(1,J), 1 )
-   50          CONTINUE
-            ELSE
-               DO 60 J = 1, M
-                  CALL DGEMV( 'NoTranspose', J, N, BETA, B, LDB, A(1,J),
-     $                        1, ALPHA, R(1,J), 1 )
-   60          CONTINUE
-            END IF
-         ELSE
-            IF( LTRANS ) THEN
-               DO 70 J = 1, M
-                  CALL DGEMV( 'NoTranspose', M-J+1, N, BETA, B(J,1),
-     $                        LDB, A(J,1), LDA, ALPHA, R(J,J), 1 )
-   70           CONTINUE
-            ELSE
-               DO 80 J = 1, M
-                  CALL DGEMV( 'NoTranspose', M-J+1, N, BETA, B(J,1),
-     $                        LDB, A(1,J), 1, ALPHA, R(J,J), 1 )
-   80          CONTINUE
-            END IF
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of MB01RX ***
-      END
--- a/extra/control-devel/src/MB01RY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,429 +0,0 @@
-      SUBROUTINE MB01RY( SIDE, UPLO, TRANS, M, ALPHA, BETA, R, LDR, H,
-     $                   LDH, B, LDB, DWORK, 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 either the upper or lower triangular part of one of the
-C     matrix formulas
-C        _
-C        R = alpha*R + beta*op( H )*B,                               (1)
-C        _
-C        R = alpha*R + beta*B*op( H ),                               (2)
-C                                                    _
-C     where alpha and beta are scalars, H, B, R, and R are m-by-m
-C     matrices, H is an upper Hessenberg matrix, and op( H ) is one of
-C
-C        op( H ) = H   or   op( H ) = H',  the transpose of H.
-C
-C     The result is overwritten on R.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     SIDE    CHARACTER*1
-C             Specifies whether the Hessenberg matrix H appears on the
-C             left or right in the matrix product as follows:
-C                     _
-C             = 'L':  R = alpha*R + beta*op( H )*B;
-C                     _
-C             = 'R':  R = alpha*R + beta*B*op( H ).
-C
-C     UPLO    CHARACTER*1                               _
-C             Specifies which triangles of the matrices R and R are
-C             computed and given, respectively, as follows:
-C             = 'U':  the upper triangular part;
-C             = 'L':  the lower triangular part.
-C
-C     TRANS   CHARACTER*1
-C             Specifies the form of op( H ) to be used in the matrix
-C             multiplication as follows:
-C             = 'N':  op( H ) = H;
-C             = 'T':  op( H ) = H';
-C             = 'C':  op( H ) = H'.
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER           _
-C             The order of the matrices R, R, H and B.  M >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The scalar alpha. When alpha is zero then R need not be
-C             set before entry.
-C
-C     BETA    (input) DOUBLE PRECISION
-C             The scalar beta. When beta is zero then H and B are not
-C             referenced.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,M)
-C             On entry with UPLO = 'U', the leading M-by-M upper
-C             triangular part of this array must contain the upper
-C             triangular part of the matrix R; the strictly lower
-C             triangular part of the array is not referenced.
-C             On entry with UPLO = 'L', the leading M-by-M lower
-C             triangular part of this array must contain the lower
-C             triangular part of the matrix R; the strictly upper
-C             triangular part of the array is not referenced.
-C             On exit, the leading M-by-M upper triangular part (if
-C             UPLO = 'U'), or lower triangular part (if UPLO = 'L') of
-C             this array contains the corresponding triangular part of
-C                                 _
-C             the computed matrix R.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,M).
-C
-C     H       (input) DOUBLE PRECISION array, dimension (LDH,M)
-C             On entry, the leading M-by-M upper Hessenberg part of
-C             this array must contain the upper Hessenberg part of the
-C             matrix H.
-C             The elements below the subdiagonal are not referenced,
-C             except possibly for those in the first column, which
-C             could be overwritten, but are restored on exit.
-C
-C     LDH     INTEGER
-C             The leading dimension of array H.  LDH >= MAX(1,M).
-C
-C     B       (input) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading M-by-M part of this array must
-C             contain the matrix B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,M).
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             LDWORK >= M, if  beta <> 0 and SIDE = 'L';
-C             LDWORK >= 0, if  beta =  0 or  SIDE = 'R'.
-C             This array is not referenced when beta = 0 or SIDE = 'R'.
-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     METHOD
-C
-C     The matrix expression is efficiently evaluated taking the
-C     Hessenberg/triangular structure into account. BLAS 2 operations
-C     are used. A block algorithm can be constructed; it can use BLAS 3
-C     GEMM operations for most computations, and calls of this BLAS 2
-C     algorithm for computing the triangles.
-C
-C     FURTHER COMMENTS
-C
-C     The main application of this routine is when the result should
-C     be a symmetric matrix, e.g., when B = X*op( H )', for (1), or
-C     B = op( H )'*X, for (2), where B is already available and X = X'.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1999.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, matrix algebra, matrix operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         SIDE, TRANS, UPLO
-      INTEGER           INFO, LDB, LDH, LDR, M
-      DOUBLE PRECISION  ALPHA, BETA
-C     .. Array Arguments ..
-      DOUBLE PRECISION  B(LDB,*), DWORK(*), H(LDH,*), R(LDR,*)
-C     .. Local Scalars ..
-      LOGICAL           LSIDE, LTRANS, LUPLO
-      INTEGER           I, J
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DDOT
-      EXTERNAL          DDOT, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DCOPY, DGEMV, DLASCL, DLASET, DSCAL, DSWAP,
-     $                  DTRMV, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX, MIN
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO   = 0
-      LSIDE  = LSAME( SIDE,  'L' )
-      LUPLO  = LSAME( UPLO,  'U' )
-      LTRANS = LSAME( TRANS, 'T' ) .OR. LSAME( TRANS, 'C' )
-C
-      IF(      ( .NOT.LSIDE  ).AND.( .NOT.LSAME( SIDE,  'R' ) ) )THEN
-         INFO = -1
-      ELSE IF( ( .NOT.LUPLO  ).AND.( .NOT.LSAME( UPLO,  'L' ) ) )THEN
-         INFO = -2
-      ELSE IF( ( .NOT.LTRANS ).AND.( .NOT.LSAME( TRANS, 'N' ) ) )THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDR.LT.MAX( 1, M ) ) THEN
-         INFO = -8
-      ELSE IF( LDH.LT.MAX( 1, M ) ) THEN
-         INFO = -10
-      ELSE IF( LDB.LT.MAX( 1, M ) ) THEN
-         INFO = -12
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB01RY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( M.EQ.0 )
-     $   RETURN
-C
-      IF ( BETA.EQ.ZERO ) THEN
-         IF ( ALPHA.EQ.ZERO ) THEN
-C
-C           Special case when both alpha = 0 and beta = 0.
-C
-            CALL DLASET( UPLO, M, M, ZERO, ZERO, R, LDR )
-         ELSE
-C
-C           Special case beta = 0.
-C
-            IF ( ALPHA.NE.ONE )
-     $         CALL DLASCL( UPLO, 0, 0, ONE, ALPHA, M, M, R, LDR, INFO )
-         END IF
-         RETURN
-      END IF
-C
-C     General case: beta <> 0.
-C     Compute the required triangle of (1) or (2) using BLAS 2
-C     operations.
-C
-      IF( LSIDE ) THEN
-C
-C        To avoid repeated references to the subdiagonal elements of H,
-C        these are swapped with the corresponding elements of H in the
-C        first column, and are finally restored.
-C
-         IF( M.GT.2 )
-     $      CALL DSWAP( M-2, H( 3, 2 ), LDH+1, H( 3, 1 ), 1 )
-C
-         IF( LUPLO ) THEN
-            IF ( LTRANS ) THEN
-C
-               DO 20 J = 1, M
-C
-C                 Multiply the transposed upper triangle of the leading
-C                 j-by-j submatrix of H by the leading part of the j-th
-C                 column of B.
-C
-                  CALL DCOPY( J, B( 1, J ), 1, DWORK, 1 )
-                  CALL DTRMV( 'Upper', TRANS, 'Non-unit', J, H, LDH,
-     $                        DWORK, 1 )
-C
-C                 Add the contribution of the subdiagonal of H to
-C                 the j-th column of the product.
-C
-                  DO 10 I = 1, MIN( J, M - 1 )
-                     R( I, J ) = ALPHA*R( I, J ) + BETA*( DWORK( I ) +
-     $                           H( I+1, 1 )*B( I+1, J ) )
-   10             CONTINUE
-C
-   20          CONTINUE
-C
-               R( M, M ) = ALPHA*R( M, M ) + BETA*DWORK( M )
-C
-            ELSE
-C
-               DO 40 J = 1, M
-C
-C                 Multiply the upper triangle of the leading j-by-j
-C                 submatrix of H by the leading part of the j-th column
-C                 of B.
-C
-                  CALL DCOPY( J, B( 1, J ), 1, DWORK, 1 )
-                  CALL DTRMV( 'Upper', TRANS, 'Non-unit', J, H, LDH,
-     $                        DWORK, 1 )
-                  IF( J.LT.M ) THEN
-C
-C                    Multiply the remaining right part of the leading
-C                    j-by-M submatrix of H by the trailing part of the
-C                    j-th column of B.
-C
-                     CALL DGEMV( TRANS, J, M-J, BETA, H( 1, J+1 ), LDH,
-     $                           B( J+1, J ), 1, ALPHA, R( 1, J ), 1 )
-                  ELSE
-                     CALL DSCAL( M, ALPHA, R( 1, M ), 1 )
-                  END IF
-C
-C                 Add the contribution of the subdiagonal of H to
-C                 the j-th column of the product.
-C
-                  R( 1, J ) = R( 1, J ) + BETA*DWORK( 1 )
-C
-                  DO 30 I = 2, J
-                     R( I, J ) = R( I, J ) + BETA*( DWORK( I ) +
-     $                           H( I, 1 )*B( I-1, J ) )
-   30             CONTINUE
-C
-   40          CONTINUE
-C
-            END IF
-C
-         ELSE
-C
-            IF ( LTRANS ) THEN
-C
-               DO 60 J = M, 1, -1
-C
-C                 Multiply the transposed upper triangle of the trailing
-C                 (M-j+1)-by-(M-j+1) submatrix of H by the trailing part
-C                 of the j-th column of B.
-C
-                  CALL DCOPY( M-J+1, B( J, J ), 1, DWORK( J ), 1 )
-                  CALL DTRMV( 'Upper', TRANS, 'Non-unit', M-J+1,
-     $                        H( J, J ), LDH, DWORK( J ), 1 )
-                  IF( J.GT.1 ) THEN
-C
-C                    Multiply the remaining left part of the trailing
-C                    (M-j+1)-by-(j-1) submatrix of H' by the leading
-C                    part of the j-th column of B.
-C
-                     CALL DGEMV( TRANS, J-1, M-J+1, BETA, H( 1, J ),
-     $                           LDH, B( 1, J ), 1, ALPHA, R( J, J ),
-     $                           1 )
-                  ELSE
-                     CALL DSCAL( M, ALPHA, R( 1, 1 ), 1 )
-                  END IF
-C
-C                 Add the contribution of the subdiagonal of H to
-C                 the j-th column of the product.
-C
-                  DO 50 I = J, M - 1
-                     R( I, J ) = R( I, J ) + BETA*( DWORK( I ) +
-     $                           H( I+1, 1 )*B( I+1, J ) )
-   50             CONTINUE
-C
-                  R( M, J ) = R( M, J ) + BETA*DWORK( M )
-   60          CONTINUE
-C
-            ELSE
-C
-               DO 80 J = M, 1, -1
-C
-C                 Multiply the upper triangle of the trailing
-C                 (M-j+1)-by-(M-j+1) submatrix of H by the trailing
-C                 part of the j-th column of B.
-C
-                  CALL DCOPY( M-J+1, B( J, J ), 1, DWORK( J ), 1 )
-                  CALL DTRMV( 'Upper', TRANS, 'Non-unit', M-J+1,
-     $                        H( J, J ), LDH, DWORK( J ), 1 )
-C
-C                 Add the contribution of the subdiagonal of H to
-C                 the j-th column of the product.
-C
-                  DO 70 I = MAX( J, 2 ), M
-                     R( I, J ) = ALPHA*R( I, J ) + BETA*( DWORK( I )
-     $                               + H( I, 1 )*B( I-1, J ) )
-   70             CONTINUE
-C
-   80          CONTINUE
-C
-               R( 1, 1 ) = ALPHA*R( 1, 1 ) + BETA*DWORK( 1 )
-C
-            END IF
-         END IF
-C
-         IF( M.GT.2 )
-     $      CALL DSWAP( M-2, H( 3, 2 ), LDH+1, H( 3, 1 ), 1 )
-C
-      ELSE
-C
-C        Row-wise calculations are used for H, if SIDE = 'R' and
-C        TRANS = 'T'.
-C
-         IF( LUPLO ) THEN
-            IF( LTRANS ) THEN
-               R( 1, 1 ) = ALPHA*R( 1, 1 ) +
-     $                     BETA*DDOT( M, B, LDB, H, LDH )
-C
-               DO 90 J = 2, M
-                  CALL DGEMV( 'NoTranspose', J, M-J+2, BETA,
-     $                        B( 1, J-1 ), LDB, H( J, J-1 ), LDH,
-     $                        ALPHA, R( 1, J ), 1 )
-   90          CONTINUE
-C
-            ELSE
-C
-               DO 100 J = 1, M - 1
-                  CALL DGEMV( 'NoTranspose', J, J+1, BETA, B, LDB,
-     $                        H( 1, J ), 1, ALPHA, R( 1, J ), 1 )
-  100          CONTINUE
-C
-               CALL DGEMV( 'NoTranspose', M, M, BETA, B, LDB,
-     $                     H( 1, M ), 1, ALPHA, R( 1, M ), 1 )
-C
-            END IF
-C
-         ELSE
-C
-            IF( LTRANS ) THEN
-C
-               CALL DGEMV( 'NoTranspose', M, M, BETA, B, LDB, H, LDH,
-     $                     ALPHA, R( 1, 1 ), 1 )
-C
-               DO 110 J = 2, M
-                  CALL DGEMV( 'NoTranspose', M-J+1, M-J+2, BETA,
-     $                        B( J, J-1 ), LDB, H( J, J-1 ), LDH, ALPHA,
-     $                        R( J, J ), 1 )
-  110          CONTINUE
-C
-            ELSE
-C
-               DO 120 J = 1, M - 1
-                  CALL DGEMV( 'NoTranspose', M-J+1, J+1, BETA,
-     $                        B( J, 1 ), LDB, H( 1, J ), 1, ALPHA,
-     $                        R( J, J ), 1 )
-  120          CONTINUE
-C
-               R( M, M ) = ALPHA*R( M, M ) +
-     $                     BETA*DDOT( M, B( M, 1 ), LDB, H( 1, M ), 1 )
-C
-            END IF
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of MB01RY ***
-      END
--- a/extra/control-devel/src/MB01SD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,123 +0,0 @@
-      SUBROUTINE MB01SD( JOBS, M, N, A, LDA, R, C )
-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 scale a general M-by-N matrix A using the row and column
-C     scaling factors in the vectors R and C.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBS    CHARACTER*1
-C             Specifies the scaling operation to be done, as follows:
-C             = 'R':  row scaling, i.e., A will be premultiplied
-C                     by diag(R);
-C             = 'C':  column scaling, i.e., A will be postmultiplied
-C                     by diag(C);
-C             = 'B':  both row and column scaling, i.e., A will be
-C                     replaced by diag(R) * A * diag(C).
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrix A.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrix A.  N >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the M-by-N matrix A.
-C             On exit, the scaled matrix.  See JOBS for the form of the
-C             scaled matrix.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,M).
-C
-C     R       (input) DOUBLE PRECISION array, dimension (M)
-C             The row scale factors for A.
-C             R is not referenced if JOBS = 'C'.
-C
-C     C       (input) DOUBLE PRECISION array, dimension (N)
-C             The column scale factors for A.
-C             C is not referenced if JOBS = 'R'.
-C
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, April 1998.
-C     Based on the RASP routine DMSCAL.
-C
-C    ******************************************************************
-C
-C     .. Scalar Arguments ..
-      CHARACTER          JOBS
-      INTEGER            LDA, M, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA,*), C(*), R(*)
-C     .. Local Scalars ..
-      INTEGER            I, J
-      DOUBLE PRECISION   CJ
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     .. Executable Statements ..
-C
-C     Quick return if possible.
-C
-      IF( M.EQ.0 .OR. N.EQ.0 )
-     $   RETURN
-C
-      IF( LSAME( JOBS, 'C' ) ) THEN
-C
-C        Column scaling, no row scaling.
-C
-         DO 20 J = 1, N
-            CJ = C(J)
-            DO 10 I = 1, M
-               A(I,J) = CJ*A(I,J)
-   10       CONTINUE
-   20    CONTINUE
-      ELSE IF( LSAME( JOBS, 'R' ) ) THEN
-C
-C        Row scaling, no column scaling.
-C
-         DO 40 J = 1, N
-            DO 30 I = 1, M
-               A(I,J) = R(I)*A(I,J)
-   30       CONTINUE
-   40    CONTINUE
-      ELSE IF( LSAME( JOBS, 'B' ) ) THEN
-C
-C        Row and column scaling.
-C
-         DO 60 J = 1, N
-            CJ = C(J)
-            DO 50 I = 1, M
-               A(I,J) = CJ*R(I)*A(I,J)
-   50       CONTINUE
-   60    CONTINUE
-      END IF
-C
-      RETURN
-C *** Last line of MB01SD ***
-      END
--- a/extra/control-devel/src/MB01TD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,173 +0,0 @@
-      SUBROUTINE MB01TD( N, A, LDA, B, LDB, DWORK, 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 matrix product A * B, where A and B are upper
-C     quasi-triangular matrices (that is, block upper triangular with
-C     1-by-1 or 2-by-2 diagonal blocks) with the same structure.
-C     The result is returned in the array B.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A and B.  N >= 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             upper quasi-triangular matrix A. The elements below the
-C             subdiagonal are not referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the upper quasi-triangular matrix B, with the same
-C             structure as matrix A.
-C             On exit, the leading N-by-N part of this array contains
-C             the computed product A * B, with the same structure as
-C             on entry.
-C             The elements below the subdiagonal are not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.  LDB >= max(1,N).
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (N-1)
-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 matrices A and B have not the same structure,
-C                   and/or A and B are not upper quasi-triangular.
-C
-C     METHOD
-C
-C     The matrix product A * B is computed column by column, using
-C     BLAS 2 and BLAS 1 operations.
-C
-C     FURTHER COMMENTS
-C
-C     This routine can be used, for instance, for computing powers of
-C     a real Schur form matrix.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, June 1998.
-C
-C     REVISIONS
-C
-C     V. Sima, Feb. 2000.
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, matrix operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER           INFO, LDA, LDB, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), DWORK(*)
-C     .. Local Scalars ..
-      INTEGER           I, J, JMIN, JMNM
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DTRMV, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX, MIN
-C
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO  = 0
-      IF( N.LT.0 ) THEN
-         INFO = -1
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -3
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -5
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB01TD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return, if possible.
-C
-      IF ( N.EQ.0 ) THEN
-         RETURN
-      ELSE IF ( N.EQ.1 ) THEN
-         B(1,1) = A(1,1)*B(1,1)
-         RETURN
-      END IF
-C
-C     Test the upper quasi-triangular structure of A and B for identity.
-C
-      DO 10 I = 1, N - 1
-         IF ( A(I+1,I).EQ.ZERO ) THEN
-            IF ( B(I+1,I).NE.ZERO ) THEN
-               INFO = 1
-               RETURN
-            END IF
-         ELSE IF ( I.LT.N-1 ) THEN
-            IF ( A(I+2,I+1).NE.ZERO ) THEN
-               INFO = 1
-               RETURN
-            END IF
-         END IF
-   10 CONTINUE
-C
-      DO 30 J = 1, N
-         JMIN = MIN( J+1,  N )
-         JMNM = MIN( JMIN, N-1 )
-C
-C        Compute the contribution of the subdiagonal of A to the
-C        j-th column of the product.
-C
-         DO 20 I = 1, JMNM
-            DWORK(I) = A(I+1,I)*B(I,J)
-   20    CONTINUE
-C
-C        Multiply the upper triangle of A by the j-th column of B,
-C        and add to the above result.
-C
-         CALL DTRMV( 'Upper', 'No transpose', 'Non-unit', JMIN, A, LDA,
-     $               B(1,J), 1 )
-         CALL DAXPY( JMNM, ONE, DWORK, 1, B(2,J), 1 )
-   30 CONTINUE
-C
-      RETURN
-C *** Last line of MB01TD ***
-      END
--- a/extra/control-devel/src/MB01UD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,238 +0,0 @@
-      SUBROUTINE MB01UD( SIDE, TRANS, M, N, ALPHA, H, LDH, A, LDA, B,
-     $                   LDB, 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 one of the matrix products
-C
-C        B = alpha*op( H ) * A, or B = alpha*A * op( H ),
-C
-C     where alpha is a scalar, A and B are m-by-n matrices, H is an
-C     upper Hessenberg matrix, and op( H ) is one of
-C
-C        op( H ) = H   or   op( H ) = H',  the transpose of H.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     SIDE    CHARACTER*1
-C             Specifies whether the Hessenberg matrix H appears on the
-C             left or right in the matrix product as follows:
-C             = 'L':  B = alpha*op( H ) * A;
-C             = 'R':  B = alpha*A * op( H ).
-C
-C     TRANS   CHARACTER*1
-C             Specifies the form of op( H ) to be used in the matrix
-C             multiplication as follows:
-C             = 'N':  op( H ) = H;
-C             = 'T':  op( H ) = H';
-C             = 'C':  op( H ) = H'.
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrices A and B.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrices A and B.  N >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The scalar alpha. When alpha is zero then H is not
-C             referenced and A need not be set before entry.
-C
-C     H       (input) DOUBLE PRECISION array, dimension (LDH,k)
-C             where k is M when SIDE = 'L' and is N when SIDE = 'R'.
-C             On entry with SIDE = 'L', the leading M-by-M upper
-C             Hessenberg part of this array must contain the upper
-C             Hessenberg matrix H.
-C             On entry with SIDE = 'R', the leading N-by-N upper
-C             Hessenberg part of this array must contain the upper
-C             Hessenberg matrix H.
-C             The elements below the subdiagonal are not referenced,
-C             except possibly for those in the first column, which
-C             could be overwritten, but are restored on exit.
-C
-C     LDH     INTEGER
-C             The leading dimension of the array H.  LDH >= max(1,k),
-C             where k is M when SIDE = 'L' and is N when SIDE = 'R'.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,N)
-C             The leading M-by-N part of this array must contain the
-C             matrix A.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,M).
-C
-C     B       (output) DOUBLE PRECISION array, dimension (LDB,N)
-C             The leading M-by-N part of this array contains the
-C             computed product.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.  LDB >= max(1,M).
-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     METHOD
-C
-C     The required matrix product is computed in two steps. In the first
-C     step, the upper triangle of H is used; in the second step, the
-C     contribution of the subdiagonal is added. A fast BLAS 3 DTRMM
-C     operation is used in the first step.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, January 1999.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, matrix operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         SIDE, TRANS
-      INTEGER           INFO, LDA, LDB, LDH, M, N
-      DOUBLE PRECISION  ALPHA
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), H(LDH,*)
-C     .. Local Scalars ..
-      LOGICAL           LSIDE, LTRANS
-      INTEGER           I, J
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DLACPY, DLASET, DSWAP, DTRMM, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX, MIN
-C
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO   = 0
-      LSIDE  = LSAME( SIDE,  'L' )
-      LTRANS = LSAME( TRANS, 'T' ) .OR. LSAME( TRANS, 'C' )
-C
-      IF(      ( .NOT.LSIDE  ).AND.( .NOT.LSAME( SIDE,  'R' ) ) )THEN
-         INFO = -1
-      ELSE IF( ( .NOT.LTRANS ).AND.( .NOT.LSAME( TRANS, 'N' ) ) )THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDH.LT.1 .OR. ( LSIDE .AND. LDH.LT.M ) .OR.
-     $                  ( .NOT.LSIDE .AND. LDH.LT.N ) ) THEN
-         INFO = -7
-      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
-         INFO = -9
-      ELSE IF( LDB.LT.MAX( 1, M ) ) THEN
-         INFO = -11
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB01UD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return, if possible.
-C
-      IF ( MIN( M, N ).EQ.0 )
-     $   RETURN
-C
-      IF( ALPHA.EQ.ZERO ) THEN
-C
-C        Set B to zero and return.
-C
-         CALL DLASET( 'Full', M, N, ZERO, ZERO, B, LDB )
-         RETURN
-      END IF
-C
-C     Copy A in B and compute one of the matrix products
-C       B = alpha*op( triu( H ) ) * A, or
-C       B = alpha*A * op( triu( H ) ),
-C     involving the upper triangle of H.
-C
-      CALL DLACPY( 'Full', M, N, A, LDA, B, LDB )
-      CALL DTRMM( SIDE, 'Upper', TRANS, 'Non-unit', M, N, ALPHA, H,
-     $            LDH, B, LDB )
-C
-C     Add the contribution of the subdiagonal of H.
-C     If SIDE = 'L', the subdiagonal of H is swapped with the
-C     corresponding elements in the first column of H, and the
-C     calculations are organized for column operations.
-C
-      IF( LSIDE ) THEN
-         IF( M.GT.2 )
-     $      CALL DSWAP( M-2, H( 3, 2 ), LDH+1, H( 3, 1 ), 1 )
-         IF( LTRANS ) THEN
-            DO 20 J = 1, N
-               DO 10 I = 1, M - 1
-                  B( I, J ) = B( I, J ) + ALPHA*H( I+1, 1 )*A( I+1, J )
-   10          CONTINUE
-   20       CONTINUE
-         ELSE
-            DO 40 J = 1, N
-               DO 30 I = 2, M
-                  B( I, J ) = B( I, J ) + ALPHA*H( I, 1 )*A( I-1, J )
-   30          CONTINUE
-   40       CONTINUE
-         END IF
-         IF( M.GT.2 )
-     $      CALL DSWAP( M-2, H( 3, 2 ), LDH+1, H( 3, 1 ), 1 )
-C
-      ELSE
-C
-         IF( LTRANS ) THEN
-            DO 50 J = 1, N - 1
-               IF ( H( J+1, J ).NE.ZERO )
-     $            CALL DAXPY( M, ALPHA*H( J+1, J ), A( 1, J ), 1,
-     $                        B( 1, J+1 ), 1 )
-   50       CONTINUE
-         ELSE
-            DO 60 J = 1, N - 1
-               IF ( H( J+1, J ).NE.ZERO )
-     $            CALL DAXPY( M, ALPHA*H( J+1, J ), A( 1, J+1 ), 1,
-     $                        B( 1, J ), 1 )
-   60       CONTINUE
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of MB01UD ***
-      END
--- a/extra/control-devel/src/MB01VD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1693 +0,0 @@
-      SUBROUTINE MB01VD( TRANA, TRANB, MA, NA, MB, NB, ALPHA, BETA,
-     $                   A, LDA, B, LDB, C, LDC, MC, NC, 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 perform the following matrix operation
-C
-C        C = alpha*kron( op(A), op(B) ) + beta*C,
-C
-C     where alpha and beta are real scalars, op(M) is either matrix M or
-C     its transpose, M', and kron( X, Y ) denotes the Kronecker product
-C     of the matrices X and Y.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used as follows:
-C             = 'N':  op(A) = A;
-C             = 'T':  op(A) = A';
-C             = 'C':  op(A) = A'.
-C
-C     TRANB   CHARACTER*1
-C             Specifies the form of op(B) to be used as follows:
-C             = 'N':  op(B) = B;
-C             = 'T':  op(B) = B';
-C             = 'C':  op(B) = B'.
-C
-C     Input/Output Parameters
-C
-C     MA      (input) INTEGER
-C             The number of rows of the matrix op(A).  MA >= 0.
-C
-C     NA      (input) INTEGER
-C             The number of columns of the matrix op(A).  NA >= 0.
-C
-C     MB      (input) INTEGER
-C             The number of rows of the matrix op(B).  MB >= 0.
-C
-C     NB      (input) INTEGER
-C             The number of columns of the matrix op(B).  NB >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The scalar alpha. When alpha is zero then A and B need not
-C             be set before entry.
-C
-C     BETA    (input) DOUBLE PRECISION
-C             The scalar beta. When beta is zero then C need not be
-C             set before entry.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,ka),
-C             where ka is NA when TRANA = 'N', and is MA otherwise.
-C             If TRANA = 'N', the leading MA-by-NA part of this array
-C             must contain the matrix A; otherwise, the leading NA-by-MA
-C             part of this array must contain the matrix A.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.
-C             LDA >= max(1,MA), if TRANA = 'N';
-C             LDA >= max(1,NA), if TRANA = 'T' or 'C'.
-C
-C     B       (input) DOUBLE PRECISION array, dimension (LDB,kb)
-C             where kb is NB when TRANB = 'N', and is MB otherwise.
-C             If TRANB = 'N', the leading MB-by-NB part of this array
-C             must contain the matrix B; otherwise, the leading NB-by-MB
-C             part of this array must contain the matrix B.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.
-C             LDB >= max(1,MB), if TRANB = 'N';
-C             LDB >= max(1,NB), if TRANB = 'T' or 'C'.
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,NC)
-C             On entry, if beta is nonzero, the leading MC-by-NC part of
-C             this array must contain the given matric C, where
-C             MC = MA*MB and NC = NA*NB.
-C             On exit, the leading MC-by-NC part of this array contains
-C             the computed matrix expression
-C             C = alpha*kron( op(A), op(B) ) + beta*C.
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.
-C             LDC >= max(1,MC).
-C
-C     MC      (output) INTEGER
-C             The number of rows of the matrix C.  MC = MA*MB.
-C
-C     NC      (output) INTEGER
-C             The number of columns of the matrix C.  NC = NA*NB.
-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     METHOD
-C
-C     The Kronecker product of the matrices op(A) and op(B) is computed
-C     column by column.
-C
-C     FURTHER COMMENTS
-C
-C     The multiplications by zero elements in A are avoided, if the
-C     matrix A is considered to be sparse, i.e., if
-C     (number of zeros in A)/(MA*NA) >= SPARST = 0.8. The code makes
-C     NB+1 passes through the matrix A, and MA*NA passes through the
-C     matrix B. If LDA and/or LDB are very large, and op(A) = A' and/or
-C     op(B) = B', it could be more efficient to transpose A and/or B
-C     before calling this routine, and use the 'N' values for TRANA
-C     and/or TRANB.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, February 2000.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, matrix operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-      DOUBLE PRECISION  SPARST
-      PARAMETER         ( SPARST = 0.8D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         TRANA, TRANB
-      INTEGER           INFO, LDA, LDB, LDC, MA, MB, MC, NA, NB, NC
-      DOUBLE PRECISION  ALPHA, BETA
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*)
-C     .. Local Scalars ..
-      LOGICAL           SPARSE, TRANSA, TRANSB
-      INTEGER           I, IC, J, JC, K, L, LC, NZ
-      DOUBLE PRECISION  AIJ
-C     .. Local Arrays ..
-      DOUBLE PRECISION  DUM(1)
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DCOPY, DLASET, DSCAL, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, MAX
-C
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      TRANSA = LSAME( TRANA, 'T' ) .OR. LSAME( TRANA, 'C' )
-      TRANSB = LSAME( TRANB, 'T' ) .OR. LSAME( TRANB, 'C' )
-      MC     = MA*MB
-      INFO   = 0
-      IF( .NOT.( TRANSA .OR. LSAME( TRANA, 'N' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( TRANSB .OR. LSAME( TRANB, 'N' ) ) ) THEN
-         INFO = -2
-      ELSE IF( MA.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( NA.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( MB.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( NB.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( ( TRANSA .AND. LDA.LT.NA ) .OR. LDA.LT.1 .OR.
-     $    ( .NOT.TRANSA .AND. LDA.LT.MA ) ) THEN
-         INFO = -10
-      ELSE IF( ( TRANSB .AND. LDB.LT.NB ) .OR. LDB.LT.1 .OR.
-     $    ( .NOT.TRANSB .AND. LDB.LT.MB ) ) THEN
-         INFO = -12
-      ELSE IF( LDC.LT.MAX( 1, MC ) ) THEN
-         INFO = -14
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB01VD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return, if possible.
-C
-      NC = NA*NB
-      IF ( MC.EQ.0 .OR. NC.EQ.0 )
-     $   RETURN
-C
-      IF ( ALPHA.EQ.ZERO ) THEN
-         IF ( BETA.EQ.ZERO ) THEN
-            CALL DLASET( 'Full', MC, NC, ZERO, ZERO, C, LDC )
-         ELSE IF ( BETA.NE.ONE ) THEN
-C
-            DO 10 J = 1, NC
-               CALL DSCAL( MC, BETA, C(1,J), 1 )
-   10       CONTINUE
-C
-         END IF
-         RETURN
-      END IF
-C
-      DUM(1) = ZERO
-      JC = 1
-      NZ = 0
-C
-C     Compute the Kronecker product of the matrices op(A) and op(B),
-C        C = alpha*kron( op(A), op(B) ) + beta*C.
-C     First, check if A is sparse. Here, A is considered as being sparse
-C     if (number of zeros in A)/(MA*NA) >= SPARST.
-C
-      DO 30 J = 1, NA
-C
-         DO 20 I = 1, MA
-            IF ( TRANSA ) THEN
-               IF ( A(J,I).EQ.ZERO )
-     $            NZ = NZ + 1
-            ELSE
-               IF ( A(I,J).EQ.ZERO )
-     $            NZ = NZ + 1
-            END IF
-   20    CONTINUE
-C
-   30 CONTINUE
-C
-      SPARSE = DBLE( NZ )/DBLE( MA*NA ).GE.SPARST
-C
-      IF ( .NOT.TRANSA .AND. .NOT.TRANSB ) THEN
-C
-C        Case op(A) = A and op(B) = B.
-C
-         IF ( BETA.EQ.ZERO ) THEN
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 0, alpha = 1, A sparse.
-C
-                  DO 80 J = 1, NA
-C
-                     DO 70 K = 1, NB
-                        IC = 1
-C
-                        DO 60 I = 1, MA
-                           AIJ = A(I,J)
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DCOPY( MB, DUM(1), 0, C(IC,JC), 1 )
-                           ELSE IF ( AIJ.EQ.ONE ) THEN
-                              CALL DCOPY( MB, B(1,K), 1, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 50 L = 1, MB
-                                 C(LC,JC) = AIJ*B(L,K)
-                                 LC = LC + 1
-   50                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-   60                   CONTINUE
-C
-                        JC = JC + 1
-   70                CONTINUE
-C
-   80             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 0, alpha = 1, A not sparse.
-C
-                  DO 120 J = 1, NA
-C
-                     DO 110 K = 1, NB
-                        IC = 1
-C
-                        DO 100 I = 1, MA
-                           AIJ = A(I,J)
-                           LC = IC
-C
-                           DO 90 L = 1, MB
-                              C(LC,JC) = AIJ*B(L,K)
-                              LC = LC + 1
-   90                      CONTINUE
-C
-                           IC = IC + MB
-  100                   CONTINUE
-C
-                        JC = JC + 1
-  110                CONTINUE
-C
-  120             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 0, alpha <> 1, A sparse.
-C
-                  DO 160 J = 1, NA
-C
-                     DO 150 K = 1, NB
-                        IC = 1
-C
-                        DO 140 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DCOPY( MB, DUM(1), 0, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 130 L = 1, MB
-                                 C(LC,JC) = AIJ*B(L,K)
-                                 LC = LC + 1
-  130                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  140                   CONTINUE
-C
-                        JC = JC + 1
-  150                CONTINUE
-C
-  160             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 0, alpha <> 1, A not sparse.
-C
-                  DO 200 J = 1, NA
-C
-                     DO 190 K = 1, NB
-                        IC = 1
-C
-                        DO 180 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-                           LC = IC
-C
-                           DO 170 L = 1, MB
-                              C(LC,JC) = AIJ*B(L,K)
-                              LC = LC + 1
-  170                      CONTINUE
-C
-                           IC = IC + MB
-  180                   CONTINUE
-C
-                        JC = JC + 1
-  190                CONTINUE
-C
-  200             CONTINUE
-C
-               END IF
-            END IF
-         ELSE IF ( BETA.EQ.ONE ) THEN
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 1, alpha = 1, A sparse.
-C
-                  DO 240 J = 1, NA
-C
-                     DO 230 K = 1, NB
-                        IC = 1
-C
-                        DO 220 I = 1, MA
-                           AIJ = A(I,J)
-                           IF ( AIJ.NE.ZERO ) THEN
-                              LC = IC
-C
-                              DO 210 L = 1, MB
-                                 C(LC,JC) = C(LC,JC) + AIJ*B(L,K)
-                                 LC = LC + 1
-  210                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  220                   CONTINUE
-C
-                        JC = JC + 1
-  230                CONTINUE
-C
-  240             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 1, alpha = 1, A not sparse.
-C
-                  DO 280 J = 1, NA
-C
-                     DO 270 K = 1, NB
-                        IC = 1
-C
-                        DO 260 I = 1, MA
-                           AIJ = A(I,J)
-                           LC = IC
-C
-                           DO 250 L = 1, MB
-                              C(LC,JC) = C(LC,JC) + AIJ*B(L,K)
-                              LC = LC + 1
-  250                      CONTINUE
-C
-                           IC = IC + MB
-  260                   CONTINUE
-C
-                        JC = JC + 1
-  270                CONTINUE
-C
-  280             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 1, alpha <> 1, A sparse.
-C
-                  DO 320 J = 1, NA
-C
-                     DO 310 K = 1, NB
-                        IC = 1
-C
-                        DO 300 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-                           IF ( AIJ.NE.ZERO ) THEN
-                              LC = IC
-C
-                              DO 290 L = 1, MB
-                                 C(LC,JC) = C(LC,JC) + AIJ*B(L,K)
-                                 LC = LC + 1
-  290                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  300                   CONTINUE
-C
-                        JC = JC + 1
-  310                CONTINUE
-C
-  320             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 1, alpha <> 1, A not sparse.
-C
-                  DO 360 J = 1, NA
-C
-                     DO 350 K = 1, NB
-                        IC = 1
-C
-                        DO 340 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-                           LC = IC
-C
-                           DO 330 L = 1, MB
-                              C(LC,JC) = C(LC,JC) + AIJ*B(L,K)
-                              LC = LC + 1
-  330                      CONTINUE
-C
-                           IC = IC + MB
-  340                   CONTINUE
-C
-                        JC = JC + 1
-  350                CONTINUE
-C
-  360             CONTINUE
-C
-               END IF
-            END IF
-         ELSE
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta <> 0 or 1, alpha = 1, A sparse.
-C
-                  DO 400 J = 1, NA
-C
-                     DO 390 K = 1, NB
-                        IC = 1
-C
-                        DO 380 I = 1, MA
-                           AIJ = A(I,J)
-C
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DSCAL( MB, BETA, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 370 L = 1, MB
-                                 C(LC,JC) = BETA*C(LC,JC) + AIJ*B(L,K)
-                                 LC = LC + 1
-  370                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  380                   CONTINUE
-C
-                        JC = JC + 1
-  390                CONTINUE
-C
-  400             CONTINUE
-C
-               ELSE
-C
-C                 Case beta <> 0 or 1, alpha = 1, A not sparse.
-C
-                  DO 440 J = 1, NA
-C
-                     DO 430 K = 1, NB
-                        IC = 1
-C
-                        DO 420 I = 1, MA
-                           AIJ = A(I,J)
-                           LC = IC
-C
-                           DO 410 L = 1, MB
-                              C(LC,JC) = BETA*C(LC,JC) + AIJ*B(L,K)
-                              LC = LC + 1
-  410                      CONTINUE
-C
-                           IC = IC + MB
-  420                   CONTINUE
-C
-                        JC = JC + 1
-  430                CONTINUE
-C
-  440             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta <> 0 or 1, alpha <> 1, A sparse.
-C
-                  DO 480 J = 1, NA
-C
-                     DO 470 K = 1, NB
-                        IC = 1
-C
-                        DO 460 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-C
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DSCAL( MB, BETA, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 450 L = 1, MB
-                                 C(LC,JC) = BETA*C(LC,JC) + AIJ*B(L,K)
-                                 LC = LC + 1
-  450                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  460                   CONTINUE
-C
-                        JC = JC + 1
-  470                CONTINUE
-C
-  480             CONTINUE
-C
-               ELSE
-C
-C                 Case beta <> 0 or 1, alpha <> 1, A not sparse.
-C
-                  DO 520 J = 1, NA
-C
-                     DO 510 K = 1, NB
-                        IC = 1
-C
-                        DO 500 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-                           LC = IC
-C
-                           DO 490 L = 1, MB
-                              C(LC,JC) = BETA*C(LC,JC) + AIJ*B(L,K)
-                              LC = LC + 1
-  490                      CONTINUE
-C
-                           IC = IC + MB
-  500                   CONTINUE
-C
-                        JC = JC + 1
-  510                CONTINUE
-C
-  520             CONTINUE
-C
-               END IF
-            END IF
-         END IF
-      ELSE IF ( TRANSA .AND. .NOT.TRANSB ) THEN
-C
-C        Case op(A) = A' and op(B) = B.
-C
-         IF ( BETA.EQ.ZERO ) THEN
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 0, alpha = 1, A sparse.
-C
-                  DO 560 J = 1, NA
-C
-                     DO 550 K = 1, NB
-                        IC = 1
-C
-                        DO 540 I = 1, MA
-                           AIJ = A(J,I)
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DCOPY( MB, DUM(1), 0, C(IC,JC), 1 )
-                           ELSE IF ( AIJ.EQ.ONE ) THEN
-                              CALL DCOPY( MB, B(1,K), 1, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 530 L = 1, MB
-                                 C(LC,JC) = AIJ*B(L,K)
-                                 LC = LC + 1
-  530                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  540                   CONTINUE
-C
-                        JC = JC + 1
-  550                CONTINUE
-C
-  560             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 0, alpha = 1, A not sparse.
-C
-                  DO 600 J = 1, NA
-C
-                     DO 590 K = 1, NB
-                        IC = 1
-C
-                        DO 580 I = 1, MA
-                           AIJ = A(J,I)
-                           LC = IC
-C
-                           DO 570 L = 1, MB
-                              C(LC,JC) = AIJ*B(L,K)
-                              LC = LC + 1
-  570                      CONTINUE
-C
-                           IC = IC + MB
-  580                   CONTINUE
-C
-                        JC = JC + 1
-  590                CONTINUE
-C
-  600             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 0, alpha <> 1, A sparse.
-C
-                  DO 640 J = 1, NA
-C
-                     DO 630 K = 1, NB
-                        IC = 1
-C
-                        DO 620 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DCOPY( MB, DUM(1), 0, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 610 L = 1, MB
-                                 C(LC,JC) = AIJ*B(L,K)
-                                 LC = LC + 1
-  610                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  620                   CONTINUE
-C
-                        JC = JC + 1
-  630                CONTINUE
-C
-  640             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 0, alpha <> 1, A not sparse.
-C
-                  DO 680 J = 1, NA
-C
-                     DO 670 K = 1, NB
-                        IC = 1
-C
-                        DO 660 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-                           LC = IC
-C
-                           DO 650 L = 1, MB
-                              C(LC,JC) = AIJ*B(L,K)
-                              LC = LC + 1
-  650                      CONTINUE
-C
-                           IC = IC + MB
-  660                   CONTINUE
-C
-                        JC = JC + 1
-  670                CONTINUE
-C
-  680             CONTINUE
-C
-               END IF
-            END IF
-         ELSE IF ( BETA.EQ.ONE ) THEN
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 1, alpha = 1, A sparse.
-C
-                  DO 720 J = 1, NA
-C
-                     DO 710 K = 1, NB
-                        IC = 1
-C
-                        DO 700 I = 1, MA
-                           AIJ = A(J,I)
-                           IF ( AIJ.NE.ZERO ) THEN
-                              LC = IC
-C
-                              DO 690 L = 1, MB
-                                 C(LC,JC) = C(LC,JC) + AIJ*B(L,K)
-                                 LC = LC + 1
-  690                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  700                   CONTINUE
-C
-                        JC = JC + 1
-  710                CONTINUE
-C
-  720             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 1, alpha = 1, A not sparse.
-C
-                  DO 760 J = 1, NA
-C
-                     DO 750 K = 1, NB
-                        IC = 1
-C
-                        DO 740 I = 1, MA
-                           AIJ = A(J,I)
-                           LC = IC
-C
-                           DO 730 L = 1, MB
-                              C(LC,JC) = C(LC,JC) + AIJ*B(L,K)
-                              LC = LC + 1
-  730                      CONTINUE
-C
-                           IC = IC + MB
-  740                   CONTINUE
-C
-                        JC = JC + 1
-  750                CONTINUE
-C
-  760             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 1, alpha <> 1, A sparse.
-C
-                  DO 800 J = 1, NA
-C
-                     DO 790 K = 1, NB
-                        IC = 1
-C
-                        DO 780 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-                           IF ( AIJ.NE.ZERO ) THEN
-                              LC = IC
-C
-                              DO 770 L = 1, MB
-                                 C(LC,JC) = C(LC,JC) + AIJ*B(L,K)
-                                 LC = LC + 1
-  770                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  780                   CONTINUE
-C
-                        JC = JC + 1
-  790                CONTINUE
-C
-  800             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 1, alpha <> 1, A not sparse.
-C
-                  DO 840 J = 1, NA
-C
-                     DO 830 K = 1, NB
-                        IC = 1
-C
-                        DO 820 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-                           LC = IC
-C
-                           DO 810 L = 1, MB
-                              C(LC,JC) = C(LC,JC) + AIJ*B(L,K)
-                              LC = LC + 1
-  810                      CONTINUE
-C
-                           IC = IC + MB
-  820                   CONTINUE
-C
-                        JC = JC + 1
-  830                CONTINUE
-C
-  840             CONTINUE
-C
-               END IF
-            END IF
-         ELSE
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta <> 0 or 1, alpha = 1, A sparse.
-C
-                  DO 880 J = 1, NA
-C
-                     DO 870 K = 1, NB
-                        IC = 1
-C
-                        DO 860 I = 1, MA
-                           AIJ = A(J,I)
-C
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DSCAL( MB, BETA, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 850 L = 1, MB
-                                 C(LC,JC) = BETA*C(LC,JC) + AIJ*B(L,K)
-                                 LC = LC + 1
-  850                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  860                   CONTINUE
-C
-                        JC = JC + 1
-  870                CONTINUE
-C
-  880             CONTINUE
-C
-               ELSE
-C
-C                 Case beta <> 0 or 1, alpha = 1, A not sparse.
-C
-                  DO 920 J = 1, NA
-C
-                     DO 910 K = 1, NB
-                        IC = 1
-C
-                        DO 900 I = 1, MA
-                           AIJ = A(J,I)
-                           LC = IC
-C
-                           DO 890 L = 1, MB
-                              C(LC,JC) = BETA*C(LC,JC) + AIJ*B(L,K)
-                              LC = LC + 1
-  890                      CONTINUE
-C
-                           IC = IC + MB
-  900                   CONTINUE
-C
-                        JC = JC + 1
-  910                CONTINUE
-C
-  920             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta <> 0 or 1, alpha <> 1, A sparse.
-C
-                  DO 960 J = 1, NA
-C
-                     DO 950 K = 1, NB
-                        IC = 1
-C
-                        DO 940 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-C
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DSCAL( MB, BETA, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 930 L = 1, MB
-                                 C(LC,JC) = BETA*C(LC,JC) + AIJ*B(L,K)
-                                 LC = LC + 1
-  930                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
-  940                   CONTINUE
-C
-                        JC = JC + 1
-  950                CONTINUE
-C
-  960             CONTINUE
-C
-               ELSE
-C
-C                 Case beta <> 0 or 1, alpha <> 1, A not sparse.
-C
-                  DO 1000 J = 1, NA
-C
-                     DO 990 K = 1, NB
-                        IC = 1
-C
-                        DO 980 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-                           LC = IC
-C
-                           DO 970 L = 1, MB
-                              C(LC,JC) = BETA*C(LC,JC) + AIJ*B(L,K)
-                              LC = LC + 1
-  970                      CONTINUE
-C
-                           IC = IC + MB
-  980                   CONTINUE
-C
-                        JC = JC + 1
-  990                CONTINUE
-C
- 1000             CONTINUE
-C
-               END IF
-            END IF
-         END IF
-      ELSE IF ( TRANSB .AND. .NOT.TRANSA ) THEN
-C
-C        Case op(A) = A and op(B) = B'.
-C
-         IF ( BETA.EQ.ZERO ) THEN
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 0, alpha = 1, A sparse.
-C
-                  DO 1080 J = 1, NA
-C
-                     DO 1070 K = 1, NB
-                        IC = 1
-C
-                        DO 1060 I = 1, MA
-                           AIJ = A(I,J)
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DCOPY( MB, DUM(1), 0, C(IC,JC), 1 )
-                           ELSE IF ( AIJ.EQ.ONE ) THEN
-                              CALL DCOPY( MB, B(K,1), LDB, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 1050 L = 1, MB
-                                 C(LC,JC) = AIJ*B(K,L)
-                                 LC = LC + 1
- 1050                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1060                   CONTINUE
-C
-                        JC = JC + 1
- 1070                CONTINUE
-C
- 1080             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 0, alpha = 1, A not sparse.
-C
-                  DO 1120 J = 1, NA
-C
-                     DO 1110 K = 1, NB
-                        IC = 1
-C
-                        DO 1100 I = 1, MA
-                           AIJ = A(I,J)
-                           LC = IC
-C
-                           DO 1090 L = 1, MB
-                              C(LC,JC) = AIJ*B(K,L)
-                              LC = LC + 1
- 1090                      CONTINUE
-C
-                           IC = IC + MB
- 1100                   CONTINUE
-C
-                        JC = JC + 1
- 1110                CONTINUE
-C
- 1120             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 0, alpha <> 1, A sparse.
-C
-                  DO 1160 J = 1, NA
-C
-                     DO 1150 K = 1, NB
-                        IC = 1
-C
-                        DO 1140 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DCOPY( MB, DUM(1), 0, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 1130 L = 1, MB
-                                 C(LC,JC) = AIJ*B(K,L)
-                                 LC = LC + 1
- 1130                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1140                   CONTINUE
-C
-                        JC = JC + 1
- 1150                CONTINUE
-C
- 1160             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 0, alpha <> 1, A not sparse.
-C
-                  DO 1200 J = 1, NA
-C
-                     DO 1190 K = 1, NB
-                        IC = 1
-C
-                        DO 1180 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-                           LC = IC
-C
-                           DO 1170 L = 1, MB
-                              C(LC,JC) = AIJ*B(K,L)
-                              LC = LC + 1
- 1170                      CONTINUE
-C
-                           IC = IC + MB
- 1180                   CONTINUE
-C
-                        JC = JC + 1
- 1190                CONTINUE
-C
- 1200             CONTINUE
-C
-               END IF
-            END IF
-         ELSE IF ( BETA.EQ.ONE ) THEN
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 1, alpha = 1, A sparse.
-C
-                  DO 1240 J = 1, NA
-C
-                     DO 1230 K = 1, NB
-                        IC = 1
-C
-                        DO 1220 I = 1, MA
-                           AIJ = A(I,J)
-                           IF ( AIJ.NE.ZERO ) THEN
-                              LC = IC
-C
-                              DO 1210 L = 1, MB
-                                 C(LC,JC) = C(LC,JC) + AIJ*B(K,L)
-                                 LC = LC + 1
- 1210                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1220                   CONTINUE
-C
-                        JC = JC + 1
- 1230                CONTINUE
-C
- 1240             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 1, alpha = 1, A not sparse.
-C
-                  DO 1280 J = 1, NA
-C
-                     DO 1270 K = 1, NB
-                        IC = 1
-C
-                        DO 1260 I = 1, MA
-                           AIJ = A(I,J)
-                           LC = IC
-C
-                           DO 1250 L = 1, MB
-                              C(LC,JC) = C(LC,JC) + AIJ*B(K,L)
-                              LC = LC + 1
- 1250                      CONTINUE
-C
-                           IC = IC + MB
- 1260                   CONTINUE
-C
-                        JC = JC + 1
- 1270                CONTINUE
-C
- 1280             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 1, alpha <> 1, A sparse.
-C
-                  DO 1320 J = 1, NA
-C
-                     DO 1310 K = 1, NB
-                        IC = 1
-C
-                        DO 1300 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-                           IF ( AIJ.NE.ZERO ) THEN
-                              LC = IC
-C
-                              DO 1290 L = 1, MB
-                                 C(LC,JC) = C(LC,JC) + AIJ*B(K,L)
-                                 LC = LC + 1
- 1290                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1300                   CONTINUE
-C
-                        JC = JC + 1
- 1310                CONTINUE
-C
- 1320             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 1, alpha <> 1, A not sparse.
-C
-                  DO 1360 J = 1, NA
-C
-                     DO 1350 K = 1, NB
-                        IC = 1
-C
-                        DO 1340 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-                           LC = IC
-C
-                           DO 1330 L = 1, MB
-                              C(LC,JC) = C(LC,JC) + AIJ*B(K,L)
-                              LC = LC + 1
- 1330                      CONTINUE
-C
-                           IC = IC + MB
- 1340                   CONTINUE
-C
-                        JC = JC + 1
- 1350                CONTINUE
-C
- 1360             CONTINUE
-C
-               END IF
-            END IF
-         ELSE
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta <> 0 or 1, alpha = 1, A sparse.
-C
-                  DO 1400 J = 1, NA
-C
-                     DO 1390 K = 1, NB
-                        IC = 1
-C
-                        DO 1380 I = 1, MA
-                           AIJ = A(I,J)
-C
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DSCAL( MB, BETA, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 1370 L = 1, MB
-                                 C(LC,JC) = BETA*C(LC,JC) + AIJ*B(K,L)
-                                 LC = LC + 1
- 1370                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1380                   CONTINUE
-C
-                        JC = JC + 1
- 1390                CONTINUE
-C
- 1400             CONTINUE
-C
-               ELSE
-C
-C                 Case beta <> 0 or 1, alpha = 1, A not sparse.
-C
-                  DO 1440 J = 1, NA
-C
-                     DO 1430 K = 1, NB
-                        IC = 1
-C
-                        DO 1420 I = 1, MA
-                           AIJ = A(I,J)
-                           LC = IC
-C
-                           DO 1410 L = 1, MB
-                              C(LC,JC) = BETA*C(LC,JC) + AIJ*B(K,L)
-                              LC = LC + 1
- 1410                      CONTINUE
-C
-                           IC = IC + MB
- 1420                   CONTINUE
-C
-                        JC = JC + 1
- 1430                CONTINUE
-C
- 1440             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta <> 0 or 1, alpha <> 1, A sparse.
-C
-                  DO 1480 J = 1, NA
-C
-                     DO 1470 K = 1, NB
-                        IC = 1
-C
-                        DO 1460 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-C
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DSCAL( MB, BETA, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 1450 L = 1, MB
-                                 C(LC,JC) = BETA*C(LC,JC) + AIJ*B(K,L)
-                                 LC = LC + 1
- 1450                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1460                   CONTINUE
-C
-                        JC = JC + 1
- 1470                CONTINUE
-C
- 1480             CONTINUE
-C
-               ELSE
-C
-C                 Case beta <> 0 or 1, alpha <> 1, A not sparse.
-C
-                  DO 1520 J = 1, NA
-C
-                     DO 1510 K = 1, NB
-                        IC = 1
-C
-                        DO 1500 I = 1, MA
-                           AIJ = ALPHA*A(I,J)
-                           LC = IC
-C
-                           DO 1490 L = 1, MB
-                              C(LC,JC) = BETA*C(LC,JC) + AIJ*B(K,L)
-                              LC = LC + 1
- 1490                      CONTINUE
-C
-                           IC = IC + MB
- 1500                   CONTINUE
-C
-                        JC = JC + 1
- 1510                CONTINUE
-C
- 1520             CONTINUE
-C
-               END IF
-            END IF
-         END IF
-      ELSE
-C
-C        Case op(A) = A' and op(B) = B'.
-C
-         IF ( BETA.EQ.ZERO ) THEN
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 0, alpha = 1, A sparse.
-C
-                  DO 1580 J = 1, NA
-C
-                     DO 1570 K = 1, NB
-                        IC = 1
-C
-                        DO 1560 I = 1, MA
-                           AIJ = A(J,I)
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DCOPY( MB, DUM(1), 0, C(IC,JC), 1 )
-                           ELSE IF ( AIJ.EQ.ONE ) THEN
-                              CALL DCOPY( MB, B(K,1), LDB, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 1550 L = 1, MB
-                                 C(LC,JC) = AIJ*B(K,L)
-                                 LC = LC + 1
- 1550                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1560                   CONTINUE
-C
-                        JC = JC + 1
- 1570                CONTINUE
-C
- 1580             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 0, alpha = 1, A not sparse.
-C
-                  DO 1620 J = 1, NA
-C
-                     DO 1610 K = 1, NB
-                        IC = 1
-C
-                        DO 1600 I = 1, MA
-                           AIJ = A(J,I)
-                           LC = IC
-C
-                           DO 1590 L = 1, MB
-                              C(LC,JC) = AIJ*B(K,L)
-                              LC = LC + 1
- 1590                      CONTINUE
-C
-                           IC = IC + MB
- 1600                   CONTINUE
-C
-                        JC = JC + 1
- 1610                CONTINUE
-C
- 1620             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 0, alpha <> 1, A sparse.
-C
-                  DO 1660 J = 1, NA
-C
-                     DO 1650 K = 1, NB
-                        IC = 1
-C
-                        DO 1640 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DCOPY( MB, DUM(1), 0, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 1630 L = 1, MB
-                                 C(LC,JC) = AIJ*B(K,L)
-                                 LC = LC + 1
- 1630                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1640                   CONTINUE
-C
-                        JC = JC + 1
- 1650                CONTINUE
-C
- 1660             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 0, alpha <> 1, A not sparse.
-C
-                  DO 1700 J = 1, NA
-C
-                     DO 1690 K = 1, NB
-                        IC = 1
-C
-                        DO 1680 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-                           LC = IC
-C
-                           DO 1670 L = 1, MB
-                              C(LC,JC) = AIJ*B(K,L)
-                              LC = LC + 1
- 1670                      CONTINUE
-C
-                           IC = IC + MB
- 1680                   CONTINUE
-C
-                        JC = JC + 1
- 1690                CONTINUE
-C
- 1700             CONTINUE
-C
-               END IF
-            END IF
-         ELSE IF ( BETA.EQ.ONE ) THEN
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 1, alpha = 1, A sparse.
-C
-                  DO 1740 J = 1, NA
-C
-                     DO 1730 K = 1, NB
-                        IC = 1
-C
-                        DO 1720 I = 1, MA
-                           AIJ = A(J,I)
-                           IF ( AIJ.NE.ZERO ) THEN
-                              LC = IC
-C
-                              DO 1710 L = 1, MB
-                                 C(LC,JC) = C(LC,JC) + AIJ*B(K,L)
-                                 LC = LC + 1
- 1710                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1720                   CONTINUE
-C
-                        JC = JC + 1
- 1730                CONTINUE
-C
- 1740             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 1, alpha = 1, A not sparse.
-C
-                  DO 1780 J = 1, NA
-C
-                     DO 1770 K = 1, NB
-                        IC = 1
-C
-                        DO 1760 I = 1, MA
-                           AIJ = A(J,I)
-                           LC = IC
-C
-                           DO 1750 L = 1, MB
-                              C(LC,JC) = C(LC,JC) + AIJ*B(K,L)
-                              LC = LC + 1
- 1750                      CONTINUE
-C
-                           IC = IC + MB
- 1760                   CONTINUE
-C
-                        JC = JC + 1
- 1770                CONTINUE
-C
- 1780             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta = 1, alpha <> 1, A sparse.
-C
-                  DO 1820 J = 1, NA
-C
-                     DO 1810 K = 1, NB
-                        IC = 1
-C
-                        DO 1800 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-                           IF ( AIJ.NE.ZERO ) THEN
-                              LC = IC
-C
-                              DO 1790 L = 1, MB
-                                 C(LC,JC) = C(LC,JC) + AIJ*B(K,L)
-                                 LC = LC + 1
- 1790                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1800                   CONTINUE
-C
-                        JC = JC + 1
- 1810                CONTINUE
-C
- 1820             CONTINUE
-C
-               ELSE
-C
-C                 Case beta = 1, alpha <> 1, A not sparse.
-C
-                  DO 1860 J = 1, NA
-C
-                     DO 1850 K = 1, NB
-                        IC = 1
-C
-                        DO 1840 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-                           LC = IC
-C
-                           DO 1830 L = 1, MB
-                              C(LC,JC) = C(LC,JC) + AIJ*B(K,L)
-                              LC = LC + 1
- 1830                      CONTINUE
-C
-                           IC = IC + MB
- 1840                   CONTINUE
-C
-                        JC = JC + 1
- 1850                CONTINUE
-C
- 1860             CONTINUE
-C
-               END IF
-            END IF
-         ELSE
-            IF ( ALPHA.EQ.ONE ) THEN
-               IF ( SPARSE ) THEN
-C
-C                 Case beta <> 0 or 1, alpha = 1, A sparse.
-C
-                  DO 1900 J = 1, NA
-C
-                     DO 1890 K = 1, NB
-                        IC = 1
-C
-                        DO 1880 I = 1, MA
-                           AIJ = A(J,I)
-C
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DSCAL( MB, BETA, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 1870 L = 1, MB
-                                 C(LC,JC) = BETA*C(LC,JC) + AIJ*B(K,L)
-                                 LC = LC + 1
- 1870                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1880                   CONTINUE
-C
-                        JC = JC + 1
- 1890                CONTINUE
-C
- 1900             CONTINUE
-C
-               ELSE
-C
-C                 Case beta <> 0 or 1, alpha = 1, A not sparse.
-C
-                  DO 1940 J = 1, NA
-C
-                     DO 1930 K = 1, NB
-                        IC = 1
-C
-                        DO 1920 I = 1, MA
-                           AIJ = A(J,I)
-                           LC = IC
-C
-                           DO 1910 L = 1, MB
-                              C(LC,JC) = BETA*C(LC,JC) + AIJ*B(K,L)
-                              LC = LC + 1
- 1910                      CONTINUE
-C
-                           IC = IC + MB
- 1920                   CONTINUE
-C
-                        JC = JC + 1
- 1930                CONTINUE
-C
- 1940             CONTINUE
-C
-               END IF
-            ELSE
-               IF ( SPARSE ) THEN
-C
-C                 Case beta <> 0 or 1, alpha <> 1, A sparse.
-C
-                  DO 1980 J = 1, NA
-C
-                     DO 1970 K = 1, NB
-                        IC = 1
-C
-                        DO 1960 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-C
-                           IF ( AIJ.EQ.ZERO ) THEN
-                              CALL DSCAL( MB, BETA, C(IC,JC), 1 )
-                           ELSE
-                              LC = IC
-C
-                              DO 1950 L = 1, MB
-                                 C(LC,JC) = BETA*C(LC,JC) + AIJ*B(K,L)
-                                 LC = LC + 1
- 1950                         CONTINUE
-C
-                           END IF
-                           IC = IC + MB
- 1960                   CONTINUE
-C
-                        JC = JC + 1
- 1970                CONTINUE
-C
- 1980             CONTINUE
-C
-               ELSE
-C
-C                 Case beta <> 0 or 1, alpha <> 1, A not sparse.
-C
-                  DO 2020 J = 1, NA
-C
-                     DO 2010 K = 1, NB
-                        IC = 1
-C
-                        DO 2000 I = 1, MA
-                           AIJ = ALPHA*A(J,I)
-                           LC = IC
-C
-                           DO 1990 L = 1, MB
-                              C(LC,JC) = BETA*C(LC,JC) + AIJ*B(K,L)
-                              LC = LC + 1
- 1990                      CONTINUE
-C
-                           IC = IC + MB
- 2000                   CONTINUE
-C
-                        JC = JC + 1
- 2010                CONTINUE
-C
- 2020             CONTINUE
-C
-               END IF
-            END IF
-         END IF
-      END IF
-      RETURN
-C *** Last line of MB01VD ***
-      END
--- a/extra/control-devel/src/MB01WD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,343 +0,0 @@
-      SUBROUTINE MB01WD( DICO, UPLO, TRANS, HESS, N, ALPHA, BETA, R,
-     $                   LDR, A, LDA, T, LDT, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the matrix formula
-C     _
-C     R = alpha*( op( A )'*op( T )'*op( T ) + op( T )'*op( T )*op( A ) )
-C         + beta*R,                                                  (1)
-C
-C     if DICO = 'C', or
-C     _
-C     R = alpha*( op( A )'*op( T )'*op( T )*op( A ) -  op( T )'*op( T ))
-C         + beta*R,                                                  (2)
-C                                                             _
-C     if DICO = 'D', where alpha and beta are scalars, R, and R are
-C     symmetric matrices, T is a triangular matrix, A is a general or
-C     Hessenberg matrix, and op( M ) is one of
-C
-C        op( M ) = M   or   op( M ) = M'.
-C
-C     The result is overwritten on R.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the formula to be evaluated, as follows:
-C             = 'C':  formula (1), "continuous-time" case;
-C             = 'D':  formula (2), "discrete-time" case.
-C
-C     UPLO    CHARACTER*1
-C             Specifies which triangles of the symmetric matrix R and
-C             triangular matrix T are given, as follows:
-C             = 'U':  the upper triangular parts of R and T are given;
-C             = 'L':  the lower triangular parts of R and T are given;
-C
-C     TRANS   CHARACTER*1
-C             Specifies the form of op( M ) to be used, as follows:
-C             = 'N':  op( M ) = M;
-C             = 'T':  op( M ) = M';
-C             = 'C':  op( M ) = M'.
-C
-C     HESS    CHARACTER*1
-C             Specifies the form of the matrix A, as follows:
-C             = 'F':  matrix A is full;
-C             = 'H':  matrix A is Hessenberg (or Schur), either upper
-C                     (if UPLO = 'U'), or lower (if UPLO = 'L').
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices R, A, and T.  N >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The scalar alpha. When alpha is zero then the arrays A
-C             and T are not referenced.
-C
-C     BETA    (input) DOUBLE PRECISION
-C             The scalar beta. When beta is zero then the array R need
-C             not be set before entry.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,N)
-C             On entry with UPLO = 'U', the leading N-by-N upper
-C             triangular part of this array must contain the upper
-C             triangular part of the symmetric matrix R.
-C             On entry with UPLO = 'L', the leading N-by-N lower
-C             triangular part of this array must contain the lower
-C             triangular part of the symmetric matrix R.
-C             On exit, the leading N-by-N upper triangular part (if
-C             UPLO = 'U'), or lower triangular part (if UPLO = 'L'), of
-C             this array contains the corresponding triangular part of
-C                                 _
-C             the computed matrix R.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,N).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the matrix A. If HESS = 'H' the elements below the
-C             first subdiagonal, if UPLO = 'U', or above the first
-C             superdiagonal, if UPLO = 'L', need not be set to zero,
-C             and are not referenced if DICO = 'D'.
-C             On exit, the leading N-by-N part of this array contains
-C             the following matrix product
-C                alpha*T'*T*A, if TRANS = 'N', or
-C                alpha*A*T*T', otherwise,
-C             if DICO = 'C', or
-C                T*A, if TRANS = 'N', or
-C                A*T, otherwise,
-C             if DICO = 'D' (and in this case, these products have a
-C             Hessenberg form, if HESS = 'H').
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     T       (input) DOUBLE PRECISION array, dimension (LDT,N)
-C             If UPLO = 'U', the leading N-by-N upper triangular part of
-C             this array must contain the upper triangular matrix T and
-C             the strictly lower triangular part need not be set to zero
-C             (and it is not referenced).
-C             If UPLO = 'L', the leading N-by-N lower triangular part of
-C             this array must contain the lower triangular matrix T and
-C             the strictly upper triangular part need not be set to zero
-C             (and it is not referenced).
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.  LDT >= MAX(1,N).
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             = 0:  successful exit;
-C             < 0:  if INFO = -k, the k-th argument had an illegal
-C                   value.
-C
-C     METHOD
-C
-C     The matrix expression (1) or (2) is efficiently evaluated taking
-C     the structure into account. BLAS 3 operations (DTRMM, DSYRK and
-C     their specializations) are used throughout.
-C
-C     NUMERICAL ASPECTS
-C
-C     If A is a full matrix, the algorithm requires approximately
-C      3
-C     N  operations, if DICO = 'C';
-C            3
-C     7/6 x N  operations, if DICO = 'D'.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Nov. 2000.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, matrix algebra, matrix operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, HESS, TRANS, UPLO
-      INTEGER           INFO, LDA, LDR, LDT, N
-      DOUBLE PRECISION  ALPHA, BETA
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), R(LDR,*), T(LDT,*)
-C     .. Local Scalars ..
-      LOGICAL           DISCR, REDUC, TRANSP, UPPER
-      CHARACTER         NEGTRA, SIDE
-      INTEGER           I, INFO2, J
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DLASCL, DLASET, DSYRK, DTRMM, MB01YD, MB01ZD,
-     $                  XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO = 0
-      DISCR  = LSAME( DICO,  'D' )
-      UPPER  = LSAME( UPLO,  'U' )
-      TRANSP = LSAME( TRANS, 'T' ) .OR. LSAME( TRANS, 'C' )
-      REDUC  = LSAME( HESS,  'H' )
-C
-      IF(      .NOT.( DISCR  .OR. LSAME( DICO,  'C' ) ) )THEN
-         INFO = -1
-      ELSE IF( .NOT.( UPPER  .OR. LSAME( UPLO,  'L' ) ) )THEN
-         INFO = -2
-      ELSE IF( .NOT.( TRANSP .OR. LSAME( TRANS, 'N' ) ) )THEN
-         INFO = -3
-      ELSE IF( .NOT.( REDUC  .OR. LSAME( HESS,  'F' ) ) )THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( LDR.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -13
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB01WD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( N.EQ.0 )
-     $   RETURN
-C
-      IF ( ALPHA.EQ.ZERO ) THEN
-         IF ( BETA.EQ.ZERO ) THEN
-C
-C           Special case when both alpha = 0 and beta = 0.
-C
-            CALL DLASET( UPLO, N, N, ZERO, ZERO, R, LDR )
-         ELSE
-C
-C           Special case alpha = 0.
-C
-            IF ( BETA.NE.ONE )
-     $         CALL DLASCL( UPLO, 0, 0, ONE, BETA, N, N, R, LDR, INFO2 )
-         END IF
-         RETURN
-      END IF
-C
-C     General case: alpha <> 0.
-C
-C     Compute (in A) T*A, if TRANS = 'N', or
-C                    A*T, otherwise.
-C
-      IF ( TRANSP ) THEN
-         SIDE   = 'R'
-         NEGTRA = 'N'
-      ELSE
-         SIDE   = 'L'
-         NEGTRA = 'T'
-      END IF
-C
-      IF ( REDUC .AND. N.GT.2 ) THEN
-         CALL MB01ZD( SIDE, UPLO, 'NoTranspose', 'Non-unit', N, N, 1,
-     $                ONE, T, LDT, A, LDA, INFO2 )
-      ELSE
-         CALL DTRMM( SIDE, UPLO, 'NoTranspose', 'Non-unit', N, N, ONE,
-     $               T, LDT, A, LDA )
-      END IF
-C
-      IF( .NOT.DISCR ) THEN
-C
-C        Compute (in A) alpha*T'*T*A, if TRANS = 'N', or
-C                       alpha*A*T*T', otherwise.
-C
-         IF ( REDUC .AND. N.GT.2 ) THEN
-            CALL MB01ZD( SIDE, UPLO, 'Transpose', 'Non-unit', N, N, 1,
-     $                   ALPHA, T, LDT, A, LDA, INFO2 )
-         ELSE
-            CALL DTRMM( SIDE, UPLO, 'Transpose', 'Non-unit', N, N,
-     $                  ALPHA, T, LDT, A, LDA )
-         END IF
-C
-C        Compute the required triangle of the result, using symmetry.
-C
-         IF ( UPPER ) THEN
-            IF ( BETA.EQ.ZERO ) THEN
-C
-               DO 20 J = 1, N
-                  DO 10 I = 1, J
-                     R( I, J ) = A( I, J ) + A( J, I )
-   10             CONTINUE
-   20          CONTINUE
-C
-            ELSE
-C
-               DO 40 J = 1, N
-                  DO 30 I = 1, J
-                     R( I, J ) = A( I, J ) + A( J, I ) + BETA*R( I, J )
-   30             CONTINUE
-   40          CONTINUE
-C
-            END IF
-C
-         ELSE
-C
-            IF ( BETA.EQ.ZERO ) THEN
-C
-               DO 60 J = 1, N
-                  DO 50 I = J, N
-                     R( I, J ) = A( I, J ) + A( J, I )
-   50             CONTINUE
-   60          CONTINUE
-C
-            ELSE
-C
-               DO 80 J = 1, N
-                  DO 70 I = J, N
-                     R( I, J ) = A( I, J ) + A( J, I ) + BETA*R( I, J )
-   70             CONTINUE
-   80          CONTINUE
-C
-            END IF
-C
-         END IF
-C
-      ELSE
-C
-C        Compute (in R) alpha*A'*T'*T*A + beta*R, if TRANS = 'N', or
-C                       alpha*A*T*T'*A' + beta*R, otherwise.
-C
-         IF ( REDUC .AND. N.GT.2 ) THEN
-            CALL MB01YD( UPLO, NEGTRA, N, N, 1, ALPHA, BETA, A, LDA, R,
-     $                   LDR, INFO2 )
-         ELSE
-            CALL DSYRK( UPLO, NEGTRA, N, N, ALPHA, A, LDA, BETA, R,
-     $                  LDR )
-         END IF
-C
-C        Compute (in R) -alpha*T'*T + R, if TRANS = 'N', or
-C                       -alpha*T*T' + R, otherwise.
-C
-         CALL MB01YD( UPLO, NEGTRA, N, N, 0, -ALPHA, ONE, T, LDT, R,
-     $                LDR, INFO2 )
-C
-      END IF
-C
-      RETURN
-C *** Last line of MB01WD ***
-      END
--- a/extra/control-devel/src/MB01YD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,352 +0,0 @@
-      SUBROUTINE MB01YD( UPLO, TRANS, N, K, L, ALPHA, BETA, A, LDA, C,
-     $                   LDC, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To perform the symmetric rank k operations
-C
-C        C := alpha*op( A )*op( A )' + beta*C,
-C
-C     where alpha and beta are scalars, C is an n-by-n symmetric matrix,
-C     op( A ) is an n-by-k matrix, and op( A ) is one of
-C
-C        op( A ) = A   or   op( A ) = A'.
-C
-C     The matrix A has l nonzero codiagonals, either upper or lower.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     UPLO    CHARACTER*1
-C             Specifies which triangle of the symmetric matrix C
-C             is given and computed, as follows:
-C             = 'U':  the upper triangular part is given/computed;
-C             = 'L':  the lower triangular part is given/computed.
-C             UPLO also defines the pattern of the matrix A (see below).
-C
-C     TRANS   CHARACTER*1
-C             Specifies the form of op( A ) to be used, as follows:
-C             = 'N':  op( A ) = A;
-C             = 'T':  op( A ) = A';
-C             = 'C':  op( A ) = A'.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix C.  N >= 0.
-C
-C     K       (input) INTEGER
-C             The number of columns of the matrix op( A ).  K >= 0.
-C
-C     L       (input) INTEGER
-C             If UPLO = 'U', matrix A has L nonzero subdiagonals.
-C             If UPLO = 'L', matrix A has L nonzero superdiagonals.
-C             MAX(0,NR-1) >= L >= 0, if UPLO = 'U',
-C             MAX(0,NC-1) >= L >= 0, if UPLO = 'L',
-C             where NR and NC are the numbers of rows and columns of the
-C             matrix A, respectively.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The scalar alpha. When alpha is zero then the array A is
-C             not referenced.
-C
-C     BETA    (input) DOUBLE PRECISION
-C             The scalar beta. When beta is zero then the array C need
-C             not be set before entry.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,NC), where
-C             NC is K when TRANS = 'N', and is N otherwise.
-C             If TRANS = 'N', the leading N-by-K part of this array must
-C             contain the matrix A, otherwise the leading K-by-N part of
-C             this array must contain the matrix A.
-C             If UPLO = 'U', only the upper triangular part and the
-C             first L subdiagonals are referenced, and the remaining
-C             subdiagonals are assumed to be zero.
-C             If UPLO = 'L', only the lower triangular part and the
-C             first L superdiagonals are referenced, and the remaining
-C             superdiagonals are assumed to be zero.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= max(1,NR),
-C             where NR = N, if TRANS = 'N', and NR = K, otherwise.
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry with UPLO = 'U', the leading N-by-N upper
-C             triangular part of this array must contain the upper
-C             triangular part of the symmetric matrix C.
-C             On entry with UPLO = 'L', the leading N-by-N lower
-C             triangular part of this array must contain the lower
-C             triangular part of the symmetric matrix C.
-C             On exit, the leading N-by-N upper triangular part (if
-C             UPLO = 'U'), or lower triangular part (if UPLO = 'L'), of
-C             this array contains the corresponding triangular part of
-C             the updated matrix C.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,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
-C     METHOD
-C
-C     The calculations are efficiently performed taking the symmetry
-C     and structure into account.
-C
-C     FURTHER COMMENTS
-C
-C     The matrix A may have the following patterns, when n = 7, k = 5,
-C     and l = 2 are used for illustration:
-C
-C     UPLO = 'U', TRANS = 'N'         UPLO = 'L', TRANS = 'N'
-C
-C            [ x x x x x ]                   [ x x x 0 0 ]
-C            [ x x x x x ]                   [ x x x x 0 ]
-C            [ x x x x x ]                   [ x x x x x ]
-C        A = [ 0 x x x x ],              A = [ x x x x x ],
-C            [ 0 0 x x x ]                   [ x x x x x ]
-C            [ 0 0 0 x x ]                   [ x x x x x ]
-C            [ 0 0 0 0 x ]                   [ x x x x x ]
-C
-C     UPLO = 'U', TRANS = 'T'         UPLO = 'L', TRANS = 'T'
-C
-C            [ x x x x x x x ]               [ x x x 0 0 0 0 ]
-C            [ x x x x x x x ]               [ x x x x 0 0 0 ]
-C        A = [ x x x x x x x ],          A = [ x x x x x 0 0 ].
-C            [ 0 x x x x x x ]               [ x x x x x x 0 ]
-C            [ 0 0 x x x x x ]               [ x x x x x x x ]
-C
-C     If N = K, the matrix A is upper or lower triangular, for L = 0,
-C     and upper or lower Hessenberg, for L = 1.
-C
-C     This routine is a specialization of the BLAS 3 routine DSYRK.
-C     BLAS 1 calls are used when appropriate, instead of in-line code,
-C     in order to increase the efficiency. If the matrix A is full, or
-C     its zero triangle has small order, an optimized DSYRK code could
-C     be faster than MB01YD.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Nov. 2000.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, matrix operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          TRANS, UPLO
-      INTEGER            INFO, LDA, LDC, K, L, N
-      DOUBLE PRECISION   ALPHA, BETA
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A( LDA, * ), C( LDC, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            TRANSP, UPPER
-      INTEGER            I, J, M, NCOLA, NROWA
-      DOUBLE PRECISION   TEMP
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DDOT
-      EXTERNAL           DDOT, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DAXPY, DLASCL, DLASET, DSCAL, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO   = 0
-      UPPER  = LSAME( UPLO,  'U' )
-      TRANSP = LSAME( TRANS, 'T' ) .OR. LSAME( TRANS, 'C' )
-C
-      IF( TRANSP )THEN
-         NROWA = K
-         NCOLA = N
-      ELSE
-         NROWA = N
-         NCOLA = K
-      END IF
-C
-      IF( UPPER )THEN
-         M = NROWA
-      ELSE
-         M = NCOLA
-      END IF
-C
-      IF(      .NOT.( UPPER  .OR. LSAME( UPLO,  'L' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( TRANSP .OR. LSAME( TRANS, 'N' ) ) ) THEN
-         INFO = -2
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( K.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( L.LT.0 .OR. L.GT.MAX( 0, M-1 ) ) THEN
-         INFO = -5
-      ELSE IF( LDA.LT.MAX( 1, NROWA ) ) THEN
-         INFO = -9
-      ELSE IF( LDC.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB01YD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return, if possible.
-C
-      IF( ( N.EQ.0 ).OR.
-     $    ( ( ( ALPHA.EQ.ZERO ).OR.( K.EQ.0 ) ).AND.( BETA.EQ.ONE ) ) )
-     $   RETURN
-C
-      IF ( ALPHA.EQ.ZERO ) THEN
-         IF ( BETA.EQ.ZERO ) THEN
-C
-C           Special case when both alpha = 0 and beta = 0.
-C
-            CALL DLASET( UPLO, N, N, ZERO, ZERO, C, LDC )
-         ELSE
-C
-C           Special case alpha = 0.
-C
-            CALL DLASCL( UPLO, 0, 0, ONE, BETA, N, N, C, LDC, INFO )
-         END IF
-         RETURN
-      END IF
-C
-C     General case: alpha <> 0.
-C
-      IF ( .NOT.TRANSP ) THEN
-C
-C        Form  C := alpha*A*A' + beta*C.
-C
-         IF ( UPPER ) THEN
-C
-            DO 30 J = 1, N
-               IF ( BETA.EQ.ZERO ) THEN
-C
-                  DO 10 I = 1, J
-                     C( I, J ) = ZERO
-   10             CONTINUE
-C
-               ELSE IF ( BETA.NE.ONE ) THEN
-                  CALL DSCAL ( J, BETA, C( 1, J ), 1 )
-               END IF
-C
-               DO 20 M = MAX( 1, J-L ), K
-                  CALL DAXPY ( MIN( J, L+M ), ALPHA*A( J, M ),
-     $                         A( 1, M ), 1, C( 1, J ), 1 )
-   20          CONTINUE
-C
-   30       CONTINUE
-C
-         ELSE
-C
-            DO 60 J = 1, N
-               IF ( BETA.EQ.ZERO ) THEN
-C
-                  DO 40 I = J, N
-                     C( I, J ) = ZERO
-   40             CONTINUE
-C
-               ELSE IF ( BETA.NE.ONE ) THEN
-                  CALL DSCAL ( N-J+1, BETA, C( J, J ), 1 )
-               END IF
-C
-               DO 50 M = 1, MIN( J+L, K )
-                  CALL DAXPY ( N-J+1, ALPHA*A( J, M ), A( J, M ), 1,
-     $                         C( J, J ), 1 )
-   50          CONTINUE
-C
-   60       CONTINUE
-C
-         END IF
-C
-      ELSE
-C
-C        Form  C := alpha*A'*A + beta*C.
-C
-         IF ( UPPER ) THEN
-C
-            DO 80 J = 1, N
-C
-               DO 70 I = 1, J
-                  TEMP = ALPHA*DDOT ( MIN( J+L, K ), A( 1, I ), 1,
-     $                                A( 1, J ), 1 )
-                  IF ( BETA.EQ.ZERO ) THEN
-                     C( I, J ) = TEMP
-                  ELSE
-                     C( I, J ) = TEMP + BETA*C( I, J )
-                  END IF
-   70          CONTINUE
-C
-   80       CONTINUE
-C
-         ELSE
-C
-            DO 100 J = 1, N
-C
-               DO 90 I = J, N
-                  M = MAX( 1, I-L )
-                  TEMP = ALPHA*DDOT ( K-M+1, A( M, I ), 1, A( M, J ),
-     $                                1 )
-                  IF ( BETA.EQ.ZERO ) THEN
-                     C( I, J ) = TEMP
-                  ELSE
-                     C( I, J ) = TEMP + BETA*C( I, J )
-                  END IF
-   90          CONTINUE
-C
-  100       CONTINUE
-C
-         END IF
-C
-      END IF
-C
-      RETURN
-C
-C *** Last line of MB01YD ***
-      END
--- a/extra/control-devel/src/MB01ZD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,475 +0,0 @@
-      SUBROUTINE MB01ZD( SIDE, UPLO, TRANST, DIAG, M, N, L, ALPHA, T,
-     $                   LDT, H, LDH, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the matrix product
-C
-C        H := alpha*op( T )*H,   or   H := alpha*H*op( T ),
-C
-C     where alpha is a scalar, H is an m-by-n upper or lower
-C     Hessenberg-like matrix (with l nonzero subdiagonals or
-C     superdiagonals, respectively), T is a unit, or non-unit,
-C     upper or lower triangular matrix, and op( T ) is one of
-C
-C        op( T ) = T   or   op( T ) = T'.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     SIDE    CHARACTER*1
-C             Specifies whether the triangular matrix T appears on the
-C             left or right in the matrix product, as follows:
-C             = 'L':  the product alpha*op( T )*H is computed;
-C             = 'R':  the product alpha*H*op( T ) is computed.
-C
-C     UPLO    CHARACTER*1
-C             Specifies the form of the matrices T and H, as follows:
-C             = 'U':  the matrix T is upper triangular and the matrix H
-C                     is upper Hessenberg-like;
-C             = 'L':  the matrix T is lower triangular and the matrix H
-C                     is lower Hessenberg-like.
-C
-C     TRANST  CHARACTER*1
-C             Specifies the form of op( T ) to be used, as follows:
-C             = 'N':  op( T ) = T;
-C             = 'T':  op( T ) = T';
-C             = 'C':  op( T ) = T'.
-C
-C     DIAG    CHARACTER*1.
-C             Specifies whether or not T is unit triangular, as follows:
-C             = 'U':  the matrix T is assumed to be unit triangular;
-C             = 'N':  the matrix T is not assumed to be unit triangular.
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of H.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of H.  N >= 0.
-C
-C     L       (input) INTEGER
-C             If UPLO = 'U', matrix H has L nonzero subdiagonals.
-C             If UPLO = 'L', matrix H has L nonzero superdiagonals.
-C             MAX(0,M-1) >= L >= 0, if UPLO = 'U';
-C             MAX(0,N-1) >= L >= 0, if UPLO = 'L'.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The scalar alpha. When alpha is zero then T is not
-C             referenced and H need not be set before entry.
-C
-C     T       (input) DOUBLE PRECISION array, dimension (LDT,k), where
-C             k is m when SIDE = 'L' and is n when SIDE = 'R'.
-C             If UPLO = 'U', the leading k-by-k upper triangular part
-C             of this array must contain the upper triangular matrix T
-C             and the strictly lower triangular part is not referenced.
-C             If UPLO = 'L', the leading k-by-k lower triangular part
-C             of this array must contain the lower triangular matrix T
-C             and the strictly upper triangular part is not referenced.
-C             Note that when DIAG = 'U', the diagonal elements of T are
-C             not referenced either, but are assumed to be unity.
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.
-C             LDT >= MAX(1,M), if SIDE = 'L';
-C             LDT >= MAX(1,N), if SIDE = 'R'.
-C
-C     H       (input/output) DOUBLE PRECISION array, dimension (LDH,N)
-C             On entry, if UPLO = 'U', the leading M-by-N upper
-C             Hessenberg part of this array must contain the upper
-C             Hessenberg-like matrix H.
-C             On entry, if UPLO = 'L', the leading M-by-N lower
-C             Hessenberg part of this array must contain the lower
-C             Hessenberg-like matrix H.
-C             On exit, the leading M-by-N part of this array contains
-C             the matrix product alpha*op( T )*H, if SIDE = 'L',
-C             or alpha*H*op( T ), if SIDE = 'R'. If TRANST = 'N', this
-C             product has the same pattern as the given matrix H;
-C             the elements below the L-th subdiagonal (if UPLO = 'U'),
-C             or above the L-th superdiagonal (if UPLO = 'L'), are not
-C             referenced in this case. If TRANST = 'T', the elements
-C             below the (N+L)-th row (if UPLO = 'U', SIDE = 'R', and
-C             M > N+L), or at the right of the (M+L)-th column
-C             (if UPLO = 'L', SIDE = 'L', and N > M+L), are not set to
-C             zero nor referenced.
-C
-C     LDH     INTEGER
-C             The leading dimension of array H.  LDH >= max(1,M).
-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     METHOD
-C
-C     The calculations are efficiently performed taking the problem
-C     structure into account.
-C
-C     FURTHER COMMENTS
-C
-C     The matrix H may have the following patterns, when m = 7, n = 6,
-C     and l = 2 are used for illustration:
-C
-C               UPLO = 'U'                    UPLO = 'L'
-C
-C            [ x x x x x x ]               [ x x x 0 0 0 ]
-C            [ x x x x x x ]               [ x x x x 0 0 ]
-C            [ x x x x x x ]               [ x x x x x 0 ]
-C        H = [ 0 x x x x x ],          H = [ x x x x x x ].
-C            [ 0 0 x x x x ]               [ x x x x x x ]
-C            [ 0 0 0 x x x ]               [ x x x x x x ]
-C            [ 0 0 0 0 x x ]               [ x x x x x x ]
-C
-C     The products T*H or H*T have the same pattern as H, but the
-C     products T'*H or H*T' may be full matrices.
-C
-C     If m = n, the matrix H is upper or lower triangular, for l = 0,
-C     and upper or lower Hessenberg, for l = 1.
-C
-C     This routine is a specialization of the BLAS 3 routine DTRMM.
-C     BLAS 1 calls are used when appropriate, instead of in-line code,
-C     in order to increase the efficiency. If the matrix H is full, or
-C     its zero triangle has small order, an optimized DTRMM code could
-C     be faster than MB01ZD.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Nov. 2000.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, matrix operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          DIAG, SIDE, TRANST, UPLO
-      INTEGER            INFO, L, LDH, LDT, M, N
-      DOUBLE PRECISION   ALPHA
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   H( LDH, * ), T( LDT, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            LSIDE, NOUNIT, TRANS, UPPER
-      INTEGER            I, I1, I2, J, K, M2, NROWT
-      DOUBLE PRECISION   TEMP
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DDOT
-      EXTERNAL           DDOT, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DAXPY, DSCAL, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      LSIDE  = LSAME( SIDE,   'L' )
-      UPPER  = LSAME( UPLO,   'U' )
-      TRANS  = LSAME( TRANST, 'T' ) .OR. LSAME( TRANST, 'C' )
-      NOUNIT = LSAME( DIAG,   'N' )
-      IF( LSIDE )THEN
-         NROWT = M
-      ELSE
-         NROWT = N
-      END IF
-C
-      IF( UPPER )THEN
-         M2 = M
-      ELSE
-         M2 = N
-      END IF
-C
-      INFO   = 0
-      IF(      .NOT.( LSIDE  .OR. LSAME( SIDE,   'R' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( UPPER  .OR. LSAME( UPLO,   'L' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.( TRANS  .OR. LSAME( TRANST, 'N' ) ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT.( NOUNIT .OR. LSAME( DIAG,   'U' ) ) ) THEN
-         INFO = -4
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( L.LT.0 .OR. L.GT.MAX( 0, M2-1 ) ) THEN
-         INFO = -7
-      ELSE IF( LDT.LT.MAX( 1, NROWT ) ) THEN
-         INFO = -10
-      ELSE IF( LDH.LT.MAX( 1, M ) )THEN
-         INFO = -12
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB01ZD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return, if possible.
-C
-      IF( MIN( M, N ).EQ.0 )
-     $   RETURN
-C
-C     Also, when alpha = 0.
-C
-      IF( ALPHA.EQ.ZERO ) THEN
-C
-         DO 20, J = 1, N
-            IF( UPPER ) THEN
-               I1 = 1
-               I2 = MIN( J+L, M )
-            ELSE
-               I1 = MAX( 1, J-L )
-               I2 = M
-            END IF
-C
-            DO 10, I = I1, I2
-               H( I, J ) = ZERO
-   10       CONTINUE
-C
-   20    CONTINUE
-C
-         RETURN
-      END IF
-C
-C     Start the operations.
-C
-      IF( LSIDE )THEN
-         IF( .NOT.TRANS ) THEN
-C
-C           Form  H := alpha*T*H.
-C
-            IF( UPPER ) THEN
-C
-               DO 40, J = 1, N
-C
-                  DO 30, K = 1, MIN( J+L, M )
-                     IF( H( K, J ).NE.ZERO ) THEN
-                        TEMP = ALPHA*H( K, J )
-                        CALL DAXPY ( K-1, TEMP, T( 1, K ), 1, H( 1, J ),
-     $                               1 )
-                        IF( NOUNIT )
-     $                     TEMP = TEMP*T( K, K )
-                        H( K, J ) = TEMP
-                     END IF
-   30             CONTINUE
-C
-   40          CONTINUE
-C
-            ELSE
-C
-               DO 60, J = 1, N
-C
-                  DO 50 K = M, MAX( 1, J-L ), -1
-                     IF( H( K, J ).NE.ZERO ) THEN
-                        TEMP      = ALPHA*H( K, J )
-                        H( K, J ) = TEMP
-                        IF( NOUNIT )
-     $                     H( K, J ) = H( K, J )*T( K, K )
-                        CALL DAXPY ( M-K, TEMP, T( K+1, K ), 1,
-     $                                          H( K+1, J ), 1 )
-                     END IF
-   50             CONTINUE
-C
-   60          CONTINUE
-C
-            END IF
-C
-         ELSE
-C
-C           Form  H := alpha*T'*H.
-C
-            IF( UPPER ) THEN
-C
-               DO 80, J = 1, N
-                  I1 = J + L
-C
-                  DO 70, I = M, 1, -1
-                     IF( I.GT.I1 ) THEN
-                        TEMP = DDOT( I1, T( 1, I ), 1, H( 1, J ), 1 )
-                     ELSE
-                        TEMP = H( I, J )
-                        IF( NOUNIT )
-     $                     TEMP = TEMP*T( I, I )
-                        TEMP = TEMP + DDOT( I-1, T( 1, I ), 1,
-     $                                           H( 1, J ), 1 )
-                     END IF
-                     H( I, J ) = ALPHA*TEMP
-   70             CONTINUE
-C
-   80          CONTINUE
-C
-            ELSE
-C
-               DO 100, J = 1, MIN( M+L, N )
-                  I1 = J - L
-C
-                  DO 90, I = 1, M
-                     IF( I.LT.I1 ) THEN
-                        TEMP = DDOT( M-I1+1, T( I1, I ), 1, H( I1, J ),
-     $                               1 )
-                     ELSE
-                        TEMP = H( I, J )
-                        IF( NOUNIT )
-     $                     TEMP = TEMP*T( I, I )
-                        TEMP = TEMP + DDOT( M-I, T( I+1, I ), 1,
-     $                                           H( I+1, J ), 1 )
-                     END IF
-                     H( I, J ) = ALPHA*TEMP
-   90             CONTINUE
-C
-  100          CONTINUE
-C
-            END IF
-C
-         END IF
-C
-      ELSE
-C
-         IF( .NOT.TRANS ) THEN
-C
-C           Form  H := alpha*H*T.
-C
-            IF( UPPER ) THEN
-C
-               DO 120, J = N, 1, -1
-                  I2   = MIN( J+L, M )
-                  TEMP = ALPHA
-                  IF( NOUNIT )
-     $               TEMP = TEMP*T( J, J )
-                  CALL DSCAL ( I2, TEMP, H( 1, J ), 1 )
-C
-                  DO 110, K = 1, J - 1
-                     CALL DAXPY ( I2, ALPHA*T( K, J ), H( 1, K ), 1,
-     $                                                 H( 1, J ), 1 )
-  110             CONTINUE
-C
-  120          CONTINUE
-C
-            ELSE
-C
-               DO 140, J = 1, N
-                  I1   = MAX( 1, J-L )
-                  TEMP = ALPHA
-                  IF( NOUNIT )
-     $               TEMP = TEMP*T( J, J )
-                  CALL DSCAL ( M-I1+1, TEMP, H( I1, J ), 1 )
-C
-                  DO 130, K = J + 1, N
-                     CALL DAXPY ( M-I1+1, ALPHA*T( K, J ), H( I1, K ),
-     $                            1, H( I1, J ), 1 )
-  130             CONTINUE
-C
-  140          CONTINUE
-C
-            END IF
-C
-         ELSE
-C
-C           Form  H := alpha*H*T'.
-C
-            IF( UPPER ) THEN
-               M2 = MIN( N+L, M )
-C
-               DO 170, K = 1, N
-                  I1 = MIN( K+L, M )
-                  I2 = MIN( K+L, M2 )
-C
-                  DO 160, J = 1, K - 1
-                     IF( T( J, K ).NE.ZERO ) THEN
-                        TEMP = ALPHA*T( J, K )
-                        CALL DAXPY ( I1, TEMP, H( 1, K ), 1, H( 1, J ),
-     $                               1 )
-C
-                        DO 150, I = I1 + 1, I2
-                           H( I, J ) = TEMP*H( I, K )
-  150                   CONTINUE
-C
-                     END IF
-  160             CONTINUE
-C
-                  TEMP = ALPHA
-                  IF( NOUNIT )
-     $               TEMP = TEMP*T( K, K )
-                  IF( TEMP.NE.ONE )
-     $               CALL DSCAL( I2, TEMP, H( 1, K ), 1 )
-  170          CONTINUE
-C
-            ELSE
-C
-               DO 200, K = N, 1, -1
-                  I1 = MAX( 1, K-L )
-                  I2 = MAX( 1, K-L+1 )
-                  M2 = MIN( M, I2-1 )
-C
-                  DO 190, J = K + 1, N
-                     IF( T( J, K ).NE.ZERO ) THEN
-                        TEMP = ALPHA*T( J, K )
-                        CALL DAXPY ( M-I2+1, TEMP, H( I2, K ), 1,
-     $                               H( I2, J ), 1 )
-C
-                        DO 180, I = I1, M2
-                           H( I, J ) = TEMP*H( I, K )
-  180                   CONTINUE
-C
-                     END IF
-  190             CONTINUE
-C
-                  TEMP = ALPHA
-                  IF( NOUNIT )
-     $               TEMP = TEMP*T( K, K )
-                  IF( TEMP.NE.ONE )
-     $               CALL DSCAL( M-I1+1, TEMP, H( I1, K ), 1 )
-  200          CONTINUE
-C
-            END IF
-C
-         END IF
-C
-      END IF
-C
-      RETURN
-C
-C *** Last line of MB01ZD ***
-      END
--- a/extra/control-devel/src/MB02PD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,553 +0,0 @@
-      SUBROUTINE MB02PD( FACT, TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV,
-     $                   EQUED, R, C, B, LDB, X, LDX, RCOND, FERR, BERR,
-     $                   IWORK, DWORK, 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 (if well-conditioned) the matrix equations
-C
-C        op( A )*X = B,
-C
-C     where X and B are N-by-NRHS matrices, A is an N-by-N matrix and
-C     op( A ) is one of
-C
-C        op( A ) = A   or   op( A ) = A'.
-C
-C     Error bounds on the solution and a condition estimate are also
-C     provided.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     FACT    CHARACTER*1
-C             Specifies whether or not the factored form of the matrix A
-C             is supplied on entry, and if not, whether the matrix A
-C             should be equilibrated before it is factored.
-C             = 'F':  On entry, AF and IPIV contain the factored form
-C                     of A. If EQUED is not 'N', the matrix A has been
-C                     equilibrated with scaling factors given by R
-C                     and C. A, AF, and IPIV are not modified.
-C             = 'N':  The matrix A will be copied to AF and factored.
-C             = 'E':  The matrix A will be equilibrated if necessary,
-C                     then copied to AF and factored.
-C
-C     TRANS   CHARACTER*1
-C             Specifies the form of the system of equations as follows:
-C             = 'N':  A * X = B     (No transpose);
-C             = 'T':  A**T * X = B  (Transpose);
-C             = 'C':  A**H * X = B  (Transpose).
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The number of linear equations, i.e., the order of the
-C             matrix A.  N >= 0.
-C
-C     NRHS    (input) INTEGER
-C             The number of right hand sides, i.e., the number of
-C             columns of the matrices B and X.  NRHS >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the matrix A.  If FACT = 'F' and EQUED is not 'N',
-C             then A must have been equilibrated by the scaling factors
-C             in R and/or C.  A is not modified if FACT = 'F' or 'N',
-C             or if FACT = 'E' and EQUED = 'N' on exit.
-C             On exit, if EQUED .NE. 'N', the leading N-by-N part of
-C             this array contains the matrix A scaled as follows:
-C             EQUED = 'R':  A := diag(R) * A;
-C             EQUED = 'C':  A := A * diag(C);
-C             EQUED = 'B':  A := diag(R) * A * diag(C).
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,N).
-C
-C     AF      (input or output) DOUBLE PRECISION array, dimension
-C             (LDAF,N)
-C             If FACT = 'F', then AF is an input argument and on entry
-C             the leading N-by-N part of this array must contain the
-C             factors L and U from the factorization A = P*L*U as
-C             computed by DGETRF.  If EQUED .NE. 'N', then AF is the
-C             factored form of the equilibrated matrix A.
-C             If FACT = 'N', then AF is an output argument and on exit
-C             the leading N-by-N part of this array contains the factors
-C             L and U from the factorization A = P*L*U of the original
-C             matrix A.
-C             If FACT = 'E', then AF is an output argument and on exit
-C             the leading N-by-N part of this array contains the factors
-C             L and U from the factorization A = P*L*U of the
-C             equilibrated matrix A (see the description of A for the
-C             form of the equilibrated matrix).
-C
-C     LDAF    (input) INTEGER
-C             The leading dimension of the array AF.  LDAF >= max(1,N).
-C
-C     IPIV    (input or output) INTEGER array, dimension (N)
-C             If FACT = 'F', then IPIV is an input argument and on entry
-C             it must contain the pivot indices from the factorization
-C             A = P*L*U as computed by DGETRF; row i of the matrix was
-C             interchanged with row IPIV(i).
-C             If FACT = 'N', then IPIV is an output argument and on exit
-C             it contains the pivot indices from the factorization
-C             A = P*L*U of the original matrix A.
-C             If FACT = 'E', then IPIV is an output argument and on exit
-C             it contains the pivot indices from the factorization
-C             A = P*L*U of the equilibrated matrix A.
-C
-C     EQUED   (input or output) CHARACTER*1
-C             Specifies the form of equilibration that was done as
-C             follows:
-C             = 'N':  No equilibration (always true if FACT = 'N');
-C             = 'R':  Row equilibration, i.e., A has been premultiplied
-C                     by diag(R);
-C             = 'C':  Column equilibration, i.e., A has been
-C                     postmultiplied by diag(C);
-C             = 'B':  Both row and column equilibration, i.e., A has
-C                     been replaced by diag(R) * A * diag(C).
-C             EQUED is an input argument if FACT = 'F'; otherwise, it is
-C             an output argument.
-C
-C     R       (input or output) DOUBLE PRECISION array, dimension (N)
-C             The row scale factors for A.  If EQUED = 'R' or 'B', A is
-C             multiplied on the left by diag(R); if EQUED = 'N' or 'C',
-C             R is not accessed.  R is an input argument if FACT = 'F';
-C             otherwise, R is an output argument.  If FACT = 'F' and
-C             EQUED = 'R' or 'B', each element of R must be positive.
-C
-C     C       (input or output) DOUBLE PRECISION array, dimension (N)
-C             The column scale factors for A.  If EQUED = 'C' or 'B',
-C             A is multiplied on the right by diag(C); if EQUED = 'N'
-C             or 'R', C is not accessed.  C is an input argument if
-C             FACT = 'F'; otherwise, C is an output argument.  If
-C             FACT = 'F' and EQUED = 'C' or 'B', each element of C must
-C             be positive.
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension
-C             (LDB,NRHS)
-C             On entry, the leading N-by-NRHS part of this array must
-C             contain the right-hand side matrix B.
-C             On exit,
-C             if EQUED = 'N', B is not modified;
-C             if TRANS = 'N' and EQUED = 'R' or 'B', the leading
-C             N-by-NRHS part of this array contains diag(R)*B;
-C             if TRANS = 'T' or 'C' and EQUED = 'C' or 'B', the leading
-C             N-by-NRHS part of this array contains diag(C)*B.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.  LDB >= max(1,N).
-C
-C     X       (output) DOUBLE PRECISION array, dimension (LDX,NRHS)
-C             If INFO = 0 or INFO = N+1, the leading N-by-NRHS part of
-C             this array contains the solution matrix X to the original
-C             system of equations.  Note that A and B are modified on
-C             exit if EQUED .NE. 'N', and the solution to the
-C             equilibrated system is inv(diag(C))*X if TRANS = 'N' and
-C             EQUED = 'C' or 'B', or inv(diag(R))*X if TRANS = 'T' or
-C             'C' and EQUED = 'R' or 'B'.
-C
-C     LDX     (input) INTEGER
-C             The leading dimension of the array X.  LDX >= max(1,N).
-C
-C     RCOND   (output) DOUBLE PRECISION
-C             The estimate of the reciprocal condition number of the
-C             matrix A after equilibration (if done).  If RCOND is less
-C             than the machine precision (in particular, if RCOND = 0),
-C             the matrix is singular to working precision.  This
-C             condition is indicated by a return code of INFO > 0.
-C             For efficiency reasons, RCOND is computed only when the
-C             matrix A is factored, i.e., for FACT = 'N' or 'E'.  For
-C             FACT = 'F', RCOND is not used, but it is assumed that it
-C             has been computed and checked before the routine call.
-C
-C     FERR    (output) DOUBLE PRECISION array, dimension (NRHS)
-C             The estimated forward error bound for each solution vector
-C             X(j) (the j-th column of the solution matrix X).
-C             If XTRUE is the true solution corresponding to X(j),
-C             FERR(j) is an estimated upper bound for the magnitude of
-C             the largest element in (X(j) - XTRUE) divided by the
-C             magnitude of the largest element in X(j).  The estimate
-C             is as reliable as the estimate for RCOND, and is almost
-C             always a slight overestimate of the true error.
-C
-C     BERR    (output) DOUBLE PRECISION array, dimension (NRHS)
-C             The componentwise relative backward error of each solution
-C             vector X(j) (i.e., the smallest relative change in
-C             any element of A or B that makes X(j) an exact solution).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (4*N)
-C             On exit, DWORK(1) contains the reciprocal pivot growth
-C             factor norm(A)/norm(U). The "max absolute element" norm is
-C             used. If DWORK(1) is much less than 1, then the stability
-C             of the LU factorization of the (equilibrated) matrix A
-C             could be poor. This also means that the solution X,
-C             condition estimator RCOND, and forward error bound FERR
-C             could be unreliable. If factorization fails with
-C             0 < INFO <= N, then DWORK(1) contains the reciprocal pivot
-C             growth factor for the leading INFO columns of A.
-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             > 0:  if INFO = i, and i is
-C                   <= N:  U(i,i) is exactly zero.  The factorization
-C                          has been completed, but the factor U is
-C                          exactly singular, so the solution and error
-C                          bounds could not be computed. RCOND = 0 is
-C                          returned.
-C                   = N+1: U is nonsingular, but RCOND is less than
-C                          machine precision, meaning that the matrix is
-C                          singular to working precision.  Nevertheless,
-C                          the solution and error bounds are computed
-C                          because there are a number of situations
-C                          where the computed solution can be more
-C                          accurate than the value of RCOND would
-C                          suggest.
-C             The positive values for INFO are set only when the
-C             matrix A is factored, i.e., for FACT = 'N' or 'E'.
-C
-C     METHOD
-C
-C     The following steps are performed:
-C
-C     1. If FACT = 'E', real scaling factors are computed to equilibrate
-C        the system:
-C
-C        TRANS = 'N':  diag(R)*A*diag(C)     *inv(diag(C))*X = diag(R)*B
-C        TRANS = 'T': (diag(R)*A*diag(C))**T *inv(diag(R))*X = diag(C)*B
-C        TRANS = 'C': (diag(R)*A*diag(C))**H *inv(diag(R))*X = diag(C)*B
-C
-C        Whether or not the system will be equilibrated depends on the
-C        scaling of the matrix A, but if equilibration is used, A is
-C        overwritten by diag(R)*A*diag(C) and B by diag(R)*B
-C        (if TRANS='N') or diag(C)*B (if TRANS = 'T' or 'C').
-C
-C     2. If FACT = 'N' or 'E', the LU decomposition is used to factor
-C        the matrix A (after equilibration if FACT = 'E') as
-C           A = P * L * U,
-C        where P is a permutation matrix, L is a unit lower triangular
-C        matrix, and U is upper triangular.
-C
-C     3. If some U(i,i)=0, so that U is exactly singular, then the
-C        routine returns with INFO = i. Otherwise, the factored form
-C        of A is used to estimate the condition number of the matrix A.
-C        If the reciprocal of the condition number is less than machine
-C        precision, INFO = N+1 is returned as a warning, but the routine
-C        still goes on to solve for X and compute error bounds as
-C        described below.
-C
-C     4. The system of equations is solved for X using the factored form
-C        of A.
-C
-C     5. Iterative refinement is applied to improve the computed
-C        solution matrix and calculate error bounds and backward error
-C        estimates for it.
-C
-C     6. If equilibration was used, the matrix X is premultiplied by
-C        diag(C) (if TRANS = 'N') or diag(R) (if TRANS = 'T' or 'C') so
-C        that it solves the original system before equilibration.
-C
-C     REFERENCES
-C
-C     [1] Anderson, E., Bai, Z., Bischof, C., Demmel, J., Dongarra, J.,
-C         Du Croz, J., Greenbaum, A., Hammarling, S., McKenney, A.,
-C         Ostrouchov, S., Sorensen, D.
-C         LAPACK Users' Guide: Second Edition, SIAM, Philadelphia, 1995.
-C
-C     FURTHER COMMENTS
-C
-C     This is a simplified version of the LAPACK Library routine DGESVX,
-C     useful when several sets of matrix equations with the same
-C     coefficient matrix  A and/or A'  should be solved.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 1999.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Condition number, matrix algebra, matrix operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         EQUED, FACT, TRANS
-      INTEGER           INFO, LDA, LDAF, LDB, LDX, N, NRHS
-      DOUBLE PRECISION  RCOND
-C     ..
-C     .. Array Arguments ..
-      INTEGER           IPIV( * ), IWORK( * )
-      DOUBLE PRECISION  A( LDA, * ), AF( LDAF, * ), B( LDB, * ),
-     $                  BERR( * ), C( * ), DWORK( * ), FERR( * ),
-     $                  R( * ), X( LDX, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL           COLEQU, EQUIL, NOFACT, NOTRAN, ROWEQU
-      CHARACTER         NORM
-      INTEGER           I, INFEQU, J
-      DOUBLE PRECISION  AMAX, ANORM, BIGNUM, COLCND, RCMAX, RCMIN,
-     $                  ROWCND, RPVGRW, SMLNUM
-C     ..
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH, DLANGE, DLANTR
-      EXTERNAL          LSAME, DLAMCH, DLANGE, DLANTR
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL          DGECON, DGEEQU, DGERFS, DGETRF, DGETRS, DLACPY,
-     $                  DLAQGE, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX, MIN
-C     ..
-C     .. Save Statement ..
-      SAVE              RPVGRW
-C     ..
-C     .. Executable Statements ..
-C
-      INFO = 0
-      NOFACT = LSAME( FACT,  'N' )
-      EQUIL  = LSAME( FACT,  'E' )
-      NOTRAN = LSAME( TRANS, 'N' )
-      IF( NOFACT .OR. EQUIL ) THEN
-         EQUED = 'N'
-         ROWEQU = .FALSE.
-         COLEQU = .FALSE.
-      ELSE
-         ROWEQU = LSAME( EQUED, 'R' ) .OR. LSAME( EQUED, 'B' )
-         COLEQU = LSAME( EQUED, 'C' ) .OR. LSAME( EQUED, 'B' )
-         SMLNUM = DLAMCH( 'Safe minimum' )
-         BIGNUM = ONE / SMLNUM
-      END IF
-C
-C     Test the input parameters.
-C
-      IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )
-     $     THEN
-         INFO = -1
-      ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
-     $                                LSAME( TRANS, 'C' ) ) THEN
-         INFO = -2
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( NRHS.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDAF.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.
-     $         ( ROWEQU .OR. COLEQU .OR. LSAME( EQUED, 'N' ) ) ) THEN
-         INFO = -10
-      ELSE
-         IF( ROWEQU ) THEN
-            RCMIN = BIGNUM
-            RCMAX = ZERO
-            DO 10 J = 1, N
-               RCMIN = MIN( RCMIN, R( J ) )
-               RCMAX = MAX( RCMAX, R( J ) )
-   10       CONTINUE
-            IF( RCMIN.LE.ZERO ) THEN
-               INFO = -11
-            ELSE IF( N.GT.0 ) THEN
-               ROWCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )
-            ELSE
-               ROWCND = ONE
-            END IF
-         END IF
-         IF( COLEQU .AND. INFO.EQ.0 ) THEN
-            RCMIN = BIGNUM
-            RCMAX = ZERO
-            DO 20 J = 1, N
-               RCMIN = MIN( RCMIN, C( J ) )
-               RCMAX = MAX( RCMAX, C( J ) )
-   20       CONTINUE
-            IF( RCMIN.LE.ZERO ) THEN
-               INFO = -12
-            ELSE IF( N.GT.0 ) THEN
-               COLCND = MAX( RCMIN, SMLNUM ) / MIN( RCMAX, BIGNUM )
-            ELSE
-               COLCND = ONE
-            END IF
-         END IF
-         IF( INFO.EQ.0 ) THEN
-            IF( LDB.LT.MAX( 1, N ) ) THEN
-               INFO = -14
-            ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
-               INFO = -16
-            END IF
-         END IF
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'MB02PD', -INFO )
-         RETURN
-      END IF
-C
-      IF( EQUIL ) THEN
-C
-C        Compute row and column scalings to equilibrate the matrix A.
-C
-         CALL DGEEQU( N, N, A, LDA, R, C, ROWCND, COLCND, AMAX, INFEQU )
-         IF( INFEQU.EQ.0 ) THEN
-C
-C           Equilibrate the matrix.
-C
-            CALL DLAQGE( N, N, A, LDA, R, C, ROWCND, COLCND, AMAX,
-     $                   EQUED )
-            ROWEQU = LSAME( EQUED, 'R' ) .OR. LSAME( EQUED, 'B' )
-            COLEQU = LSAME( EQUED, 'C' ) .OR. LSAME( EQUED, 'B' )
-         END IF
-      END IF
-C
-C     Scale the right hand side.
-C
-      IF( NOTRAN ) THEN
-         IF( ROWEQU ) THEN
-            DO 40 J = 1, NRHS
-               DO 30 I = 1, N
-                  B( I, J ) = R( I )*B( I, J )
-   30          CONTINUE
-   40       CONTINUE
-         END IF
-      ELSE IF( COLEQU ) THEN
-         DO 60 J = 1, NRHS
-            DO 50 I = 1, N
-               B( I, J ) = C( I )*B( I, J )
-   50       CONTINUE
-   60    CONTINUE
-      END IF
-C
-      IF( NOFACT .OR. EQUIL ) THEN
-C
-C        Compute the LU factorization of A.
-C
-         CALL DLACPY( 'Full', N, N, A, LDA, AF, LDAF )
-         CALL DGETRF( N, N, AF, LDAF, IPIV, INFO )
-C
-C        Return if INFO is non-zero.
-C
-         IF( INFO.NE.0 ) THEN
-            IF( INFO.GT.0 ) THEN
-C
-C              Compute the reciprocal pivot growth factor of the
-C              leading rank-deficient INFO columns of A.
-C
-               RPVGRW = DLANTR( 'M', 'U', 'N', INFO, INFO, AF, LDAF,
-     $                  DWORK )
-               IF( RPVGRW.EQ.ZERO ) THEN
-                  RPVGRW = ONE
-               ELSE
-                  RPVGRW = DLANGE( 'M', N, INFO, A, LDA, DWORK ) /
-     $                     RPVGRW
-               END IF
-               DWORK( 1 ) = RPVGRW
-               RCOND = ZERO
-            END IF
-            RETURN
-         END IF
-C
-C        Compute the norm of the matrix A and the
-C        reciprocal pivot growth factor RPVGRW.
-C
-         IF( NOTRAN ) THEN
-            NORM = '1'
-         ELSE
-            NORM = 'I'
-         END IF
-         ANORM = DLANGE( NORM, N, N, A, LDA, DWORK )
-         RPVGRW = DLANTR( 'M', 'U', 'N', N, N, AF, LDAF, DWORK )
-         IF( RPVGRW.EQ.ZERO ) THEN
-            RPVGRW = ONE
-         ELSE
-            RPVGRW = DLANGE( 'M', N, N, A, LDA, DWORK ) / RPVGRW
-         END IF
-C
-C        Compute the reciprocal of the condition number of A.
-C
-         CALL DGECON( NORM, N, AF, LDAF, ANORM, RCOND, DWORK, IWORK,
-     $                INFO )
-C
-C        Set INFO = N+1 if the matrix is singular to working precision.
-C
-         IF( RCOND.LT.DLAMCH( 'Epsilon' ) )
-     $      INFO = N + 1
-      END IF
-C
-C     Compute the solution matrix X.
-C
-      CALL DLACPY( 'Full', N, NRHS, B, LDB, X, LDX )
-      CALL DGETRS( TRANS, N, NRHS, AF, LDAF, IPIV, X, LDX, INFO )
-C
-C     Use iterative refinement to improve the computed solution and
-C     compute error bounds and backward error estimates for it.
-C
-      CALL DGERFS( TRANS, N, NRHS, A, LDA, AF, LDAF, IPIV, B, LDB, X,
-     $             LDX, FERR, BERR, DWORK, IWORK, INFO )
-C
-C     Transform the solution matrix X to a solution of the original
-C     system.
-C
-      IF( NOTRAN ) THEN
-         IF( COLEQU ) THEN
-            DO 80 J = 1, NRHS
-               DO 70 I = 1, N
-                  X( I, J ) = C( I )*X( I, J )
-   70          CONTINUE
-   80       CONTINUE
-            DO 90 J = 1, NRHS
-               FERR( J ) = FERR( J ) / COLCND
-   90       CONTINUE
-         END IF
-      ELSE IF( ROWEQU ) THEN
-         DO 110 J = 1, NRHS
-            DO 100 I = 1, N
-               X( I, J ) = R( I )*X( I, J )
-  100       CONTINUE
-  110    CONTINUE
-         DO 120 J = 1, NRHS
-            FERR( J ) = FERR( J ) / ROWCND
-  120    CONTINUE
-      END IF
-C
-      DWORK( 1 ) = RPVGRW
-      RETURN
-C
-C *** Last line of MB02PD ***
-      END
--- a/extra/control-devel/src/MB02QY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +0,0 @@
-      SUBROUTINE MB02QY( M, N, NRHS, RANK, A, LDA, JPVT, B, LDB, TAU,
-     $                   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 determine the minimum-norm solution to a real linear least
-C     squares problem:
-C
-C         minimize || A * X - B ||,
-C
-C     using the rank-revealing QR factorization of a real general
-C     M-by-N matrix  A,  computed by SLICOT Library routine  MB03OD.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrices A and B.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrix A.  N >= 0.
-C
-C     NRHS    (input) INTEGER
-C             The number of columns of the matrix B.  NRHS >= 0.
-C
-C     RANK    (input) INTEGER
-C             The effective rank of  A,  as returned by SLICOT Library
-C             routine  MB03OD.  min(M,N) >= RANK >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension
-C             ( LDA, N )
-C             On entry, the leading min(M,N)-by-N upper trapezoidal
-C             part of this array contains the triangular factor  R,  as
-C             returned by SLICOT Library routine  MB03OD.  The strict
-C             lower trapezoidal part of  A  is not referenced.
-C             On exit, if  RANK < N,  the leading  RANK-by-RANK  upper
-C             triangular part of this array contains the upper
-C             triangular matrix  R  of the complete orthogonal
-C             factorization of  A,  and the submatrix  (1:RANK,RANK+1:N)
-C             of this array, with the array  TAU,  represent the
-C             orthogonal matrix  Z  (of the complete orthogonal
-C             factorization of  A),  as a product of  RANK  elementary
-C             reflectors.
-C             On exit, if  RANK = N,  this array is unchanged.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,M).
-C
-C     JPVT    (input) INTEGER array, dimension ( N )
-C             The recorded permutations performed by SLICOT Library
-C             routine  MB03OD;  if  JPVT(i) = k,  then the i-th column
-C             of  A*P  was the k-th column of the original matrix  A.
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension
-C             ( LDB, NRHS )
-C             On entry, if  NRHS > 0,  the leading M-by-NRHS part of
-C             this array must contain the matrix  B  (corresponding to
-C             the transformed matrix  A,  returned by SLICOT Library
-C             routine  MB03OD).
-C             On exit, if  NRHS > 0,  the leading N-by-NRHS part of this
-C             array contains the solution matrix X.
-C             If  M >= N  and  RANK = N,  the residual sum-of-squares
-C             for the solution in the i-th column is given by the sum
-C             of squares of elements  N+1:M  in that column.
-C             If  NRHS = 0,  the array  B  is not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.
-C             LDB >= max(1,M,N),  if  NRHS > 0.
-C             LDB >= 1,           if  NRHS = 0.
-C
-C     TAU     (output) DOUBLE PRECISION array, dimension ( min(M,N) )
-C             The scalar factors of the elementary reflectors.
-C             If  RANK = N,  the array  TAU  is not referenced.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension ( LDWORK )
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= max( 1, N, NRHS ).
-C             For good performance,  LDWORK  should sometimes 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
-C     METHOD
-C
-C     The routine uses a QR factorization with column pivoting:
-C
-C        A * P = Q * R = Q * [ R11 R12 ],
-C                            [  0  R22 ]
-C
-C     where  R11  is an upper triangular submatrix of estimated rank
-C     RANK,  the effective rank of  A.  The submatrix  R22  can be
-C     considered as negligible.
-C
-C     If  RANK < N,  then  R12  is annihilated by orthogonal
-C     transformations from the right, arriving at the complete
-C     orthogonal factorization:
-C
-C        A * P = Q * [ T11 0 ] * Z.
-C                    [  0  0 ]
-C
-C     The minimum-norm solution is then
-C
-C        X = P * Z' [ inv(T11)*Q1'*B ],
-C                   [        0       ]
-C
-C     where Q1 consists of the first  RANK  columns of Q.
-C
-C     The input data for  MB02QY  are the transformed matrices  Q' * A
-C     (returned by SLICOT Library routine  MB03OD)  and  Q' * B.
-C     Matrix  Q  is not needed.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is numerically stable.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 1999.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Least squares solutions; QR decomposition.
-C
-C    ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER            INFO, LDA, LDB, LDWORK, M, N, NRHS, RANK
-C     .. Array Arguments ..
-      INTEGER            JPVT( * )
-      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), DWORK( * ), TAU( * )
-C     .. Local Scalars ..
-      INTEGER            I, IASCL, IBSCL, J, MN
-      DOUBLE PRECISION   ANRM, BIGNUM, BNRM, MAXWRK, SMLNUM
-C     .. External Functions ..
-      DOUBLE PRECISION   DLAMCH, DLANGE, DLANTR
-      EXTERNAL           DLAMCH, DLANGE, DLANTR
-C     .. External Subroutines ..
-      EXTERNAL           DCOPY, DLABAD, DLASCL, DLASET, DORMRZ, DTRSM,
-     $                   DTZRZF, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          DBLE, MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-      MN = MIN( M, N )
-C
-C     Test the input scalar arguments.
-C
-      INFO = 0
-      IF( M.LT.0 ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( NRHS.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( RANK.LT.0 .OR. RANK.GT.MN ) THEN
-         INFO = -4
-      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
-         INFO = -6
-      ELSE IF( LDB.LT.1 .OR. ( NRHS.GT.0 .AND. LDB.LT.MAX( M, N ) ) )
-     $      THEN
-         INFO = -9
-      ELSE IF( LDWORK.LT.MAX( 1, N, NRHS ) ) THEN
-         INFO = -12
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'MB02QY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( MN, NRHS ).EQ.0 ) THEN
-         DWORK( 1 ) = ONE
-         RETURN
-      END IF
-C
-C     Logically partition R = [ R11 R12 ],
-C                             [  0  R22 ]
-C
-C     where R11 = R(1:RANK,1:RANK).  If  RANK = N,  let  T11 = R11.
-C
-      MAXWRK = DBLE( N )
-      IF( RANK.LT.N ) THEN
-C
-C        Get machine parameters.
-C
-         SMLNUM = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )
-         BIGNUM = ONE / SMLNUM
-         CALL DLABAD( SMLNUM, BIGNUM )
-C
-C        Scale A, B if max entries outside range [SMLNUM,BIGNUM].
-C
-         ANRM = DLANTR( 'MaxNorm', 'Upper', 'Non-unit', RANK, N, A, LDA,
-     $                  DWORK )
-         IASCL = 0
-         IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
-C
-C           Scale matrix norm up to SMLNUM.
-C
-            CALL DLASCL( 'Upper', 0, 0, ANRM, SMLNUM, RANK, N, A, LDA,
-     $                   INFO )
-            IASCL = 1
-         ELSE IF( ANRM.GT.BIGNUM ) THEN
-C
-C           Scale matrix norm down to BIGNUM.
-C
-            CALL DLASCL( 'Upper', 0, 0, ANRM, BIGNUM, RANK, N, A, LDA,
-     $                   INFO )
-            IASCL = 2
-         ELSE IF( ANRM.EQ.ZERO ) THEN
-C
-C           Matrix all zero. Return zero solution.
-C
-            CALL DLASET( 'Full', N, NRHS, ZERO, ZERO, B, LDB )
-            DWORK( 1 ) = ONE
-            RETURN
-         END IF
-C
-         BNRM = DLANGE( 'MaxNorm', M, NRHS, B, LDB, DWORK )
-         IBSCL = 0
-         IF( BNRM.GT.ZERO .AND. BNRM.LT.SMLNUM ) THEN
-C
-C           Scale matrix norm up to SMLNUM.
-C
-            CALL DLASCL( 'General', 0, 0, BNRM, SMLNUM, M, NRHS, B, LDB,
-     $                   INFO )
-            IBSCL = 1
-         ELSE IF( BNRM.GT.BIGNUM ) THEN
-C
-C           Scale matrix norm down to BIGNUM.
-C
-            CALL DLASCL( 'General', 0, 0, BNRM, BIGNUM, M, NRHS, B, LDB,
-     $                   INFO )
-            IBSCL = 2
-         END IF
-C
-C        [R11,R12] = [ T11, 0 ] * Z.
-C        Details of Householder rotations are stored in TAU.
-C        Workspace need RANK, prefer RANK*NB.
-C
-         CALL DTZRZF( RANK, N, A, LDA, TAU, DWORK, LDWORK, INFO )
-         MAXWRK = MAX( MAXWRK, DWORK( 1 ) )
-      END IF
-C
-C     B(1:RANK,1:NRHS) := inv(T11) * B(1:RANK,1:NRHS).
-C
-      CALL DTRSM( 'Left', 'Upper', 'No transpose', 'Non-unit', RANK,
-     $            NRHS, ONE, A, LDA, B, LDB )
-C
-      IF( RANK.LT.N ) THEN
-C
-         CALL DLASET( 'Full', N-RANK, NRHS, ZERO, ZERO, B( RANK+1, 1 ),
-     $                LDB )
-C
-C        B(1:N,1:NRHS) := Z' * B(1:N,1:NRHS).
-C        Workspace need NRHS, prefer NRHS*NB.
-C
-         CALL DORMRZ( 'Left', 'Transpose', N, NRHS, RANK, N-RANK, A,
-     $                LDA, TAU, B, LDB, DWORK, LDWORK, INFO )
-         MAXWRK = MAX( MAXWRK, DWORK( 1 ) )
-C
-C        Undo scaling.
-C
-         IF( IASCL.EQ.1 ) THEN
-            CALL DLASCL( 'General', 0, 0, ANRM, SMLNUM, N, NRHS, B, LDB,
-     $                   INFO )
-            CALL DLASCL( 'Upper', 0, 0, SMLNUM, ANRM, RANK, RANK, A,
-     $                   LDA, INFO )
-         ELSE IF( IASCL.EQ.2 ) THEN
-            CALL DLASCL( 'General', 0, 0, ANRM, BIGNUM, N, NRHS, B, LDB,
-     $                   INFO )
-            CALL DLASCL( 'Upper', 0, 0, BIGNUM, ANRM, RANK, RANK, A,
-     $                   LDA, INFO )
-         END IF
-         IF( IBSCL.EQ.1 ) THEN
-            CALL DLASCL( 'General', 0, 0, SMLNUM, BNRM, N, NRHS, B, LDB,
-     $                   INFO )
-         ELSE IF( IBSCL.EQ.2 ) THEN
-            CALL DLASCL( 'General', 0, 0, BIGNUM, BNRM, N, NRHS, B, LDB,
-     $                   INFO )
-         END IF
-      END IF
-C
-C     B(1:N,1:NRHS) := P * B(1:N,1:NRHS).
-C     Workspace N.
-C
-      DO 20 J = 1, NRHS
-C
-         DO 10 I = 1, N
-            DWORK( JPVT( I ) ) = B( I, J )
-   10    CONTINUE
-C
-         CALL DCOPY( N, DWORK, 1, B( 1, J ), 1 )
-   20 CONTINUE
-C
-      DWORK( 1 ) = MAXWRK
-      RETURN
-C
-C *** Last line of MB02QY ***
-      END
--- a/extra/control-devel/src/MB02UD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,624 +0,0 @@
-      SUBROUTINE MB02UD( FACT, SIDE, TRANS, JOBP, M, N, ALPHA, RCOND,
-     $                   RANK, R, LDR, Q, LDQ, SV, B, LDB, RP, LDRP,
-     $                   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 compute the minimum norm least squares solution of one of the
-C     following linear systems
-C
-C        op(R)*X = alpha*B,                                          (1)
-C        X*op(R) = alpha*B,                                          (2)
-C
-C     where alpha is a real scalar, op(R) is either R or its transpose,
-C     R', R is an L-by-L real upper triangular matrix, B is an M-by-N
-C     real matrix, and L = M for (1), or L = N for (2). Singular value
-C     decomposition, R = Q*S*P', is used, assuming that R is rank
-C     deficient.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     FACT    CHARACTER*1
-C             Specifies whether R has been previously factored or not,
-C             as follows:
-C             = 'F':  R has been factored and its rank and singular
-C                     value decomposition, R = Q*S*P', are available;
-C             = 'N':  R has not been factored and its singular value
-C                     decomposition, R = Q*S*P', should be computed.
-C
-C     SIDE    CHARACTER*1
-C             Specifies whether op(R) appears on the left or right
-C             of X as follows:
-C             = 'L':  Solve op(R)*X = alpha*B  (op(R) is on the left);
-C             = 'R':  Solve X*op(R) = alpha*B  (op(R) is on the right).
-C
-C     TRANS   CHARACTER*1
-C             Specifies the form of op(R) to be used as follows:
-C             = 'N':  op(R) = R;
-C             = 'T':  op(R) = R';
-C             = 'C':  op(R) = R'.
-C
-C     JOBP    CHARACTER*1
-C             Specifies whether or not the pseudoinverse of R is to be
-C             computed or it is available as follows:
-C             = 'P':  Compute pinv(R), if FACT = 'N', or
-C                     use pinv(R),     if FACT = 'F';
-C             = 'N':  Do not compute or use pinv(R).
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrix B.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrix B.  N >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The scalar alpha. When alpha is zero then B need not be
-C             set before entry.
-C
-C     RCOND   (input) DOUBLE PRECISION
-C             RCOND is used to determine the effective rank of R.
-C             Singular values of R satisfying Sv(i) <= RCOND*Sv(1) are
-C             treated as zero. If RCOND <= 0, then EPS is used instead,
-C             where EPS is the relative machine precision (see LAPACK
-C             Library routine DLAMCH).  RCOND <= 1.
-C             RCOND is not used if FACT = 'F'.
-C
-C     RANK    (input or output) INTEGER
-C             The rank of matrix R.
-C             RANK is an input parameter when FACT = 'F', and an output
-C             parameter when FACT = 'N'.  L >= RANK >= 0.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,L)
-C             On entry, if FACT = 'F', the leading L-by-L part of this
-C             array must contain the L-by-L orthogonal matrix P' from
-C             singular value decomposition, R = Q*S*P', of the matrix R;
-C             if JOBP = 'P', the first RANK rows of P' are assumed to be
-C             scaled by inv(S(1:RANK,1:RANK)).
-C             On entry, if FACT = 'N', the leading L-by-L upper
-C             triangular part of this array must contain the upper
-C             triangular matrix R.
-C             On exit, if INFO = 0, the leading L-by-L part of this
-C             array contains the L-by-L orthogonal matrix P', with its
-C             first RANK rows scaled by inv(S(1:RANK,1:RANK)), when
-C             JOBP = 'P'.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,L).
-C
-C     Q       (input or output) DOUBLE PRECISION array, dimension
-C             (LDQ,L)
-C             On entry, if FACT = 'F', the leading L-by-L part of this
-C             array must contain the L-by-L orthogonal matrix Q from
-C             singular value decomposition, R = Q*S*P', of the matrix R.
-C             If FACT = 'N', this array need not be set on entry, and
-C             on exit, if INFO = 0, the leading L-by-L part of this
-C             array contains the orthogonal matrix Q.
-C
-C     LDQ     INTEGER
-C             The leading dimension of array Q.  LDQ >= MAX(1,L).
-C
-C     SV      (input or output) DOUBLE PRECISION array, dimension (L)
-C             On entry, if FACT = 'F', the first RANK entries of this
-C             array must contain the reciprocal of the largest RANK
-C             singular values of the matrix R, and the last L-RANK
-C             entries of this array must contain the remaining singular
-C             values of R sorted in descending order.
-C             If FACT = 'N', this array need not be set on input, and
-C             on exit, if INFO = 0, the first RANK entries of this array
-C             contain the reciprocal of the largest RANK singular values
-C             of the matrix R, and the last L-RANK entries of this array
-C             contain the remaining singular values of R sorted in
-C             descending order.
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,N)
-C             On entry, if ALPHA <> 0, the leading M-by-N part of this
-C             array must contain the matrix B.
-C             On exit, if INFO = 0 and RANK > 0, the leading M-by-N part
-C             of this array contains the M-by-N solution matrix X.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,M).
-C
-C     RP      (input or output) DOUBLE PRECISION array, dimension
-C             (LDRP,L)
-C             On entry, if FACT = 'F', JOBP = 'P', and RANK > 0, the
-C             leading L-by-L part of this array must contain the L-by-L
-C             matrix pinv(R), the Moore-Penrose pseudoinverse of R.
-C             On exit, if FACT = 'N', JOBP = 'P', and RANK > 0, the
-C             leading L-by-L part of this array contains the L-by-L
-C             matrix pinv(R), the Moore-Penrose pseudoinverse of R.
-C             If JOBP = 'N', this array is not referenced.
-C
-C     LDRP    INTEGER
-C             The leading dimension of array RP.
-C             LDRP >= MAX(1,L), if JOBP = 'P'.
-C             LDRP >= 1,        if JOBP = 'N'.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal LDWORK;
-C             if INFO = i, 1 <= i <= L, then DWORK(2:L) contain the
-C             unconverged superdiagonal elements of an upper bidiagonal
-C             matrix D whose diagonal is in SV (not necessarily sorted).
-C             D satisfies R = Q*D*P', so it has the same singular
-C             values as R, and singular vectors related by Q and P'.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1,L),   if FACT = 'F';
-C             LDWORK >= MAX(1,5*L), if FACT = 'N'.
-C             For optimum performance LDWORK should be larger than
-C             MAX(1,L,M*N),   if FACT = 'F';
-C             MAX(1,5*L,M*N), if FACT = '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             > 0:  if INFO = i, i = 1:L, the SVD algorithm has failed
-C                   to converge. In this case INFO specifies how many
-C                   superdiagonals did not converge (see the description
-C                   of DWORK); this failure is not likely to occur.
-C
-C     METHOD
-C
-C     The L-by-L upper triangular matrix R is factored as  R = Q*S*P',
-C     if FACT = 'N', using SLICOT Library routine MB03UD, where Q and P
-C     are L-by-L orthogonal matrices and S is an L-by-L diagonal matrix
-C     with non-negative diagonal elements, SV(1), SV(2), ..., SV(L),
-C     ordered decreasingly. Then, the effective rank of R is estimated,
-C     and matrix (or matrix-vector) products and scalings are used to
-C     compute X. If FACT = 'F', only matrix (or matrix-vector) products
-C     and scalings are performed.
-C
-C     FURTHER COMMENTS
-C
-C     Option JOBP = 'P' should be used only if the pseudoinverse is
-C     really needed. Usually, it is possible to avoid the use of
-C     pseudoinverse, by computing least squares solutions.
-C     The routine uses BLAS 3 calculations if LDWORK >= M*N, and BLAS 2
-C     calculations, otherwise. No advantage of any additional workspace
-C     larger than L is taken for matrix products, but the routine can
-C     be called repeatedly for chunks of columns of B, if LDWORK < M*N.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute of Informatics, Bucharest, Oct. 1999.
-C
-C     REVISIONS
-C
-C     V. Sima, Feb. 2000.
-C
-C     KEYWORDS
-C
-C     Bidiagonalization, orthogonal transformation, singular value
-C     decomposition, singular values, triangular form.
-C
-C    ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         FACT, JOBP, SIDE, TRANS
-      INTEGER           INFO, LDB, LDQ, LDR, LDRP, LDWORK, M, N, RANK
-      DOUBLE PRECISION  ALPHA, RCOND
-C     .. Array Arguments ..
-      DOUBLE PRECISION  B(LDB,*), DWORK(*), Q(LDQ,*), R(LDR,*),
-     $                  RP(LDRP,*), SV(*)
-C     .. Local Scalars ..
-      LOGICAL           LEFT, NFCT, PINV, TRAN
-      CHARACTER*1       NTRAN
-      INTEGER           I, L, MAXWRK, MINWRK, MN
-      DOUBLE PRECISION  TOLL
-C     .. External Functions ..
-      LOGICAL           LSAME
-      INTEGER           ILAENV
-      DOUBLE PRECISION  DLAMCH
-      EXTERNAL          DLAMCH, ILAENV, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DCOPY, DGEMM, DGEMV, DLACPY, DLASET, MB01SD,
-     $                  MB03UD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX, MIN
-C     .. Executable Statements ..
-C
-C     Check the input scalar arguments.
-C
-      INFO = 0
-      NFCT = LSAME( FACT,  'N' )
-      LEFT = LSAME( SIDE,  'L' )
-      PINV = LSAME( JOBP,  'P' )
-      TRAN = LSAME( TRANS, 'T' ) .OR. LSAME( TRANS, 'C' )
-      IF( LEFT ) THEN
-         L = M
-      ELSE
-         L = N
-      END IF
-      MN = M*N
-      IF( .NOT.NFCT .AND. .NOT.LSAME( FACT, 'F' ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE,  'R' ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.TRAN .AND. .NOT.LSAME( TRANS, 'N' ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT.PINV .AND. .NOT.LSAME( JOBP,  'N' ) ) THEN
-         INFO = -4
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( NFCT .AND. RCOND.GT.ONE ) THEN
-         INFO = -8
-      ELSE IF( .NOT.NFCT .AND. ( RANK.LT.ZERO .OR. RANK.GT.L ) ) THEN
-         INFO = -9
-      ELSE IF( LDR.LT.MAX( 1, L ) ) THEN
-         INFO = -11
-      ELSE IF( LDQ.LT.MAX( 1, L ) ) THEN
-         INFO = -13
-      ELSE IF( LDB.LT.MAX( 1, M ) ) THEN
-         INFO = -16
-      ELSE IF( LDRP.LT.1 .OR. ( PINV .AND. LDRP.LT.L ) ) THEN
-         INFO = -18
-      END IF
-C
-C     Compute workspace
-C     (Note: Comments in the code beginning "Workspace:" describe the
-C     minimal amount of workspace needed at that point in the code,
-C     as well as the preferred amount for good performance.
-C     NB refers to the optimal block size for the immediately following
-C     subroutine, as returned by ILAENV.)
-C
-      MINWRK = 1
-      IF( INFO.EQ.0 .AND. LDWORK.GE.1 .AND. L.GT.0 ) THEN
-         MINWRK = MAX( 1, L )
-         MAXWRK = MAX( MINWRK, MN )
-         IF( NFCT ) THEN
-            MAXWRK = MAX( MAXWRK, 3*L+2*L*
-     $                    ILAENV( 1, 'DGEBRD', ' ', L, L, -1, -1 ) )
-            MAXWRK = MAX( MAXWRK, 3*L+L*
-     $                    ILAENV( 1, 'DORGBR', 'Q', L, L, L, -1 ) )
-            MAXWRK = MAX( MAXWRK, 3*L+L*
-     $                    ILAENV( 1, 'DORGBR', 'P', L, L, L, -1 ) )
-            MINWRK = MAX( 1, 5*L )
-            MAXWRK = MAX( MAXWRK, MINWRK )
-         END IF
-      END IF
-C
-      IF( LDWORK.LT.MINWRK ) THEN
-         INFO = -20
-      END IF
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'MB02UD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( L.EQ.0 ) THEN
-         IF( NFCT )
-     $      RANK = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      IF( NFCT ) THEN
-C
-C        Compute the SVD of R, R = Q*S*P'.
-C        Matrix Q is computed in the array Q, and P' overwrites R.
-C        Workspace: need   5*L;
-C                   prefer larger.
-C
-         CALL MB03UD( 'Vectors', 'Vectors', L, R, LDR, Q, LDQ, SV,
-     $                DWORK, LDWORK, INFO )
-         IF ( INFO.NE.0 )
-     $      RETURN
-C
-C        Use the default tolerance, if required.
-C
-         TOLL = RCOND
-         IF( TOLL.LE.ZERO )
-     $      TOLL = DLAMCH( 'Precision' )
-         TOLL = MAX( TOLL*SV(1), DLAMCH( 'Safe minimum' ) )
-C
-C        Estimate the rank of R.
-C
-         DO 10 I = 1, L
-            IF ( TOLL.GT.SV(I) )
-     $         GO TO 20
-   10    CONTINUE
-C
-         I = L + 1
-   20    CONTINUE
-         RANK = I - 1
-C
-         DO 30 I = 1, RANK
-            SV(I) = ONE / SV(I)
-   30    CONTINUE
-C
-         IF( PINV .AND. RANK.GT.0 ) THEN
-C
-C           Compute  pinv(S)'*P'  in R.
-C
-            CALL MB01SD( 'Row scaling', RANK, L, R, LDR, SV, SV )
-C
-C           Compute  pinv(R) = P*pinv(S)*Q'  in  RP.
-C
-            CALL DGEMM( 'Transpose', 'Transpose', L, L, RANK, ONE, R,
-     $                  LDR, Q, LDQ, ZERO, RP, LDRP )
-         END IF
-      END IF
-C
-C     Return if min(M,N) = 0 or RANK = 0.
-C
-      IF( MIN( M, N ).EQ.0 .OR. RANK.EQ.0 ) THEN
-         DWORK(1) = MAXWRK
-         RETURN
-      END IF
-C
-C     Set X = 0 if alpha = 0.
-C
-      IF( ALPHA.EQ.ZERO ) THEN
-         CALL DLASET( 'Full', M, N, ZERO, ZERO, B, LDB )
-         DWORK(1) = MAXWRK
-         RETURN
-      END IF
-C
-      IF( PINV ) THEN
-C
-         IF( LEFT ) THEN
-C
-C           Compute  alpha*op(pinv(R))*B  in workspace and save it in B.
-C           Workspace:  need   M   (BLAS 2);
-C                       prefer M*N (BLAS 3).
-C
-            IF( LDWORK.GE.MN ) THEN
-               CALL DGEMM( TRANS, 'NoTranspose', M, N, M, ALPHA,
-     $                     RP, LDRP, B, LDB, ZERO, DWORK, M )
-               CALL DLACPY( 'Full', M, N, DWORK, M, B, LDB )
-            ELSE
-C
-               DO 40 I = 1, N
-                  CALL DGEMV( TRANS, M, M, ALPHA, RP, LDRP, B(1,I), 1,
-     $                        ZERO, DWORK, 1 )
-                  CALL DCOPY( M, DWORK, 1, B(1,I), 1 )
-   40          CONTINUE
-C
-            END IF
-         ELSE
-C
-C           Compute  alpha*B*op(pinv(R))  in workspace and save it in B.
-C           Workspace:  need   N   (BLAS 2);
-C                       prefer M*N (BLAS 3).
-C
-            IF( LDWORK.GE.MN ) THEN
-               CALL DGEMM( 'NoTranspose', TRANS, M, N, N, ALPHA, B, LDB,
-     $                     RP, LDRP, ZERO, DWORK, M )
-               CALL DLACPY( 'Full', M, N, DWORK, M, B, LDB )
-            ELSE
-C
-               IF( TRAN ) THEN
-                  NTRAN = 'N'
-               ELSE
-                  NTRAN = 'T'
-               END IF
-C
-               DO 50 I = 1, M
-                  CALL DGEMV( NTRAN, N, N, ALPHA, RP, LDRP, B(I,1), LDB,
-     $                        ZERO, DWORK, 1 )
-                  CALL DCOPY( N, DWORK, 1, B(I,1), LDB )
-   50          CONTINUE
-C
-            END IF
-         END IF
-C
-      ELSE
-C
-         IF( LEFT ) THEN
-C
-C           Compute  alpha*P*pinv(S)*Q'*B  or  alpha*Q*pinv(S)'*P'*B.
-C           Workspace:  need   M   (BLAS 2);
-C                       prefer M*N (BLAS 3).
-C
-            IF( LDWORK.GE.MN ) THEN
-               IF( TRAN ) THEN
-C
-C                 Compute  alpha*P'*B  in workspace.
-C
-                  CALL DGEMM( 'NoTranspose', 'NoTranspose', M, N, M,
-     $                        ALPHA, R, LDR, B, LDB, ZERO, DWORK, M )
-C
-C                 Compute  alpha*pinv(S)'*P'*B.
-C
-                  CALL MB01SD( 'Row scaling', RANK, N, DWORK, M, SV,
-     $                         SV )
-C
-C                 Compute  alpha*Q*pinv(S)'*P'*B.
-C
-                  CALL DGEMM( 'NoTranspose', 'NoTranspose', M, N, RANK,
-     $                        ONE, Q, LDQ, DWORK, M, ZERO, B, LDB )
-               ELSE
-C
-C                 Compute  alpha*Q'*B  in workspace.
-C
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, N, M,
-     $                        ALPHA, Q, LDQ, B, LDB, ZERO, DWORK, M )
-C
-C                 Compute  alpha*pinv(S)*Q'*B.
-C
-                  CALL MB01SD( 'Row scaling', RANK, N, DWORK, M, SV,
-     $                         SV )
-C
-C                 Compute  alpha*P*pinv(S)*Q'*B.
-C
-                  CALL DGEMM( 'Transpose', 'NoTranspose', M, N, RANK,
-     $                        ONE, R, LDR, DWORK, M, ZERO, B, LDB )
-               END IF
-            ELSE
-               IF( TRAN ) THEN
-C
-C                 Compute  alpha*P'*B  in B using workspace.
-C
-                  DO 60 I = 1, N
-                     CALL DGEMV( 'NoTranspose', M, M, ALPHA, R, LDR,
-     $                           B(1,I), 1, ZERO, DWORK, 1 )
-                     CALL DCOPY( M, DWORK, 1, B(1,I), 1 )
-   60             CONTINUE
-C
-C                 Compute  alpha*pinv(S)'*P'*B.
-C
-                  CALL MB01SD( 'Row scaling', RANK, N, B, LDB, SV, SV )
-C
-C                 Compute  alpha*Q*pinv(S)'*P'*B  in B using workspace.
-C
-                  DO 70 I = 1, N
-                     CALL DGEMV( 'NoTranspose', M, RANK, ONE, Q, LDQ,
-     $                           B(1,I), 1, ZERO, DWORK, 1 )
-                     CALL DCOPY( M, DWORK, 1, B(1,I), 1 )
-   70             CONTINUE
-               ELSE
-C
-C                 Compute  alpha*Q'*B  in B using workspace.
-C
-                  DO 80 I = 1, N
-                     CALL DGEMV( 'Transpose', M, M, ALPHA, Q, LDQ,
-     $                           B(1,I), 1, ZERO, DWORK, 1 )
-                     CALL DCOPY( M, DWORK, 1, B(1,I), 1 )
-   80             CONTINUE
-C
-C                 Compute  alpha*pinv(S)*Q'*B.
-C
-                  CALL MB01SD( 'Row scaling', RANK, N, B, LDB, SV, SV )
-C
-C                 Compute  alpha*P*pinv(S)*Q'*B  in B using workspace.
-C
-                  DO 90 I = 1, N
-                     CALL DGEMV( 'Transpose', RANK, M, ONE, R, LDR,
-     $                           B(1,I), 1, ZERO, DWORK, 1 )
-                     CALL DCOPY( M, DWORK, 1, B(1,I), 1 )
-   90             CONTINUE
-               END IF
-            END IF
-         ELSE
-C
-C           Compute  alpha*B*P*pinv(S)*Q'  or  alpha*B*Q*pinv(S)'*P'.
-C           Workspace:  need   N   (BLAS 2);
-C                       prefer M*N (BLAS 3).
-C
-            IF( LDWORK.GE.MN ) THEN
-               IF( TRAN ) THEN
-C
-C                 Compute  alpha*B*Q  in workspace.
-C
-                  CALL DGEMM( 'NoTranspose', 'NoTranspose', M, N, N,
-     $                        ALPHA, B, LDB, Q, LDQ, ZERO, DWORK, M )
-C
-C                 Compute  alpha*B*Q*pinv(S)'.
-C
-                  CALL MB01SD( 'Column scaling', M, RANK, DWORK, M, SV,
-     $                         SV )
-C
-C                 Compute  alpha*B*Q*pinv(S)'*P' in B.
-C
-                  CALL DGEMM( 'NoTranspose', 'NoTranspose', M, N, RANK,
-     $                        ONE, DWORK, M, R, LDR, ZERO, B, LDB )
-               ELSE
-C
-C                 Compute  alpha*B*P  in workspace.
-C
-                  CALL DGEMM( 'NoTranspose', 'Transpose', M, N, N,
-     $                        ALPHA, B, LDB, R, LDR, ZERO, DWORK, M )
-C
-C                 Compute  alpha*B*P*pinv(S).
-C
-                  CALL MB01SD( 'Column scaling', M, RANK, DWORK, M, SV,
-     $                         SV )
-C
-C                 Compute  alpha*B*P*pinv(S)*Q' in B.
-C
-                  CALL DGEMM( 'NoTranspose', 'Transpose', M, N, RANK,
-     $                        ONE, DWORK, M, Q, LDQ, ZERO, B, LDB )
-               END IF
-            ELSE
-               IF( TRAN ) THEN
-C
-C                 Compute  alpha*B*Q  in B using workspace.
-C
-                  DO 100 I = 1, M
-                     CALL DGEMV( 'Transpose', N, N, ALPHA, Q, LDQ,
-     $                           B(I,1), LDB, ZERO, DWORK, 1 )
-                     CALL DCOPY( N, DWORK, 1, B(I,1), LDB )
-  100             CONTINUE
-C
-C                 Compute  alpha*B*Q*pinv(S)'.
-C
-                  CALL MB01SD( 'Column scaling', M, RANK, B, LDB, SV,
-     $                         SV )
-C
-C                 Compute  alpha*B*Q*pinv(S)'*P' in B using workspace.
-C
-                  DO 110 I = 1, M
-                     CALL DGEMV( 'Transpose', RANK, N, ONE, R, LDR,
-     $                           B(I,1), LDB, ZERO, DWORK, 1 )
-                     CALL DCOPY( N, DWORK, 1, B(I,1), LDB )
-  110             CONTINUE
-C
-               ELSE
-C
-C                 Compute  alpha*B*P  in B using workspace.
-C
-                  DO 120 I = 1, M
-                     CALL DGEMV( 'NoTranspose', N, N, ALPHA, R, LDR,
-     $                           B(I,1), LDB, ZERO, DWORK, 1 )
-                     CALL DCOPY( N, DWORK, 1, B(I,1), LDB )
-  120             CONTINUE
-C
-C                 Compute  alpha*B*P*pinv(S).
-C
-                  CALL MB01SD( 'Column scaling', M, RANK, B, LDB, SV,
-     $                         SV )
-C
-C                 Compute  alpha*B*P*pinv(S)*Q' in B using workspace.
-C
-                  DO 130 I = 1, M
-                     CALL DGEMV( 'NoTranspose', N, RANK, ONE, Q, LDQ,
-     $                           B(I,1), LDB, ZERO, DWORK, 1 )
-                     CALL DCOPY( N, DWORK, 1, B(I,1), LDB )
-  130             CONTINUE
-               END IF
-            END IF
-         END IF
-      END IF
-C
-C     Return optimal workspace in DWORK(1).
-C
-      DWORK(1) = MAXWRK
-C
-      RETURN
-C *** Last line of MB02UD ***
-      END
--- a/extra/control-devel/src/MB03OD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,306 +0,0 @@
-      SUBROUTINE MB03OD( JOBQR, M, N, A, LDA, JPVT, RCOND, SVLMAX, TAU,
-     $                   RANK, SVAL, 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 compute (optionally) a rank-revealing QR factorization of a
-C     real general M-by-N matrix  A,  which may be rank-deficient,
-C     and estimate its effective rank using incremental condition
-C     estimation.
-C
-C     The routine uses a QR factorization with column pivoting:
-C        A * P = Q * R,  where  R = [ R11 R12 ],
-C                                   [  0  R22 ]
-C     with R11 defined as the largest leading submatrix whose estimated
-C     condition number is less than 1/RCOND.  The order of R11, RANK,
-C     is the effective rank of A.
-C
-C     MB03OD  does not perform any scaling of the matrix A.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBQR   CHARACTER*1
-C             = 'Q':  Perform a QR factorization with column pivoting;
-C             = 'N':  Do not perform the QR factorization (but assume
-C                     that it has been done outside).
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrix A.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrix A.  N >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension
-C             ( LDA, N )
-C             On entry with JOBQR = 'Q', the leading M by N part of this
-C             array must contain the given matrix A.
-C             On exit with JOBQR = 'Q', the leading min(M,N) by N upper
-C             triangular part of A contains the triangular factor R,
-C             and the elements below the diagonal, with the array TAU,
-C             represent the orthogonal matrix Q as a product of
-C             min(M,N) elementary reflectors.
-C             On entry and on exit with JOBQR = 'N', the leading
-C             min(M,N) by N upper triangular part of A contains the
-C             triangular factor R, as determined by the QR factorization
-C             with pivoting.  The elements below the diagonal of A are
-C             not referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,M).
-C
-C     JPVT    (input/output) INTEGER array, dimension ( N )
-C             On entry with JOBQR = 'Q', if JPVT(i) <> 0, the i-th
-C             column of A is an initial column, otherwise it is a free
-C             column. Before the QR factorization of A, all initial
-C             columns are permuted to the leading positions; only the
-C             remaining free columns are moved as a result of column
-C             pivoting during the factorization.  For rank determination
-C             it is preferable that all columns be free.
-C             On exit with JOBQR = 'Q', if JPVT(i) = k, then the i-th
-C             column of A*P was the k-th column of A.
-C             Array JPVT is not referenced when JOBQR = 'N'.
-C
-C     RCOND   (input) DOUBLE PRECISION
-C             RCOND is used to determine the effective rank of A, which
-C             is defined as the order of the largest leading triangular
-C             submatrix R11 in the QR factorization with pivoting of A,
-C             whose estimated condition number is less than 1/RCOND.
-C             RCOND >= 0.
-C             NOTE that when SVLMAX > 0, the estimated rank could be
-C             less than that defined above (see SVLMAX).
-C
-C     SVLMAX  (input) DOUBLE PRECISION
-C             If A is a submatrix of another matrix B, and the rank
-C             decision should be related to that matrix, then SVLMAX
-C             should be an estimate of the largest singular value of B
-C             (for instance, the Frobenius norm of B).  If this is not
-C             the case, the input value SVLMAX = 0 should work.
-C             SVLMAX >= 0.
-C
-C     TAU     (output) DOUBLE PRECISION array, dimension ( MIN( M, N ) )
-C             On exit with JOBQR = 'Q', the leading min(M,N) elements of
-C             TAU contain the scalar factors of the elementary
-C             reflectors.
-C             Array TAU is not referenced when JOBQR = 'N'.
-C
-C     RANK    (output) INTEGER
-C             The effective (estimated) rank of A, i.e. the order of
-C             the submatrix R11.
-C
-C     SVAL    (output) DOUBLE PRECISION array, dimension ( 3 )
-C             The estimates of some of the singular values of the
-C             triangular factor R:
-C             SVAL(1): largest singular value of R(1:RANK,1:RANK);
-C             SVAL(2): smallest singular value of R(1:RANK,1:RANK);
-C             SVAL(3): smallest singular value of R(1:RANK+1,1:RANK+1),
-C                      if RANK < MIN( M, N ), or of R(1:RANK,1:RANK),
-C                      otherwise.
-C             If the triangular factorization is a rank-revealing one
-C             (which will be the case if the leading columns were well-
-C             conditioned), then SVAL(1) will also be an estimate for
-C             the largest singular value of A, and SVAL(2) and SVAL(3)
-C             will be estimates for the RANK-th and (RANK+1)-st singular
-C             values of A, respectively.
-C             By examining these values, one can confirm that the rank
-C             is well defined with respect to the chosen value of RCOND.
-C             The ratio SVAL(1)/SVAL(2) is an estimate of the condition
-C             number of R(1:RANK,1:RANK).
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension ( LDWORK )
-C             On exit, if  INFO = 0,  DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 3*N + 1,                 if JOBQR = 'Q';
-C             LDWORK >= max( 1, 2*min( M, N ) ), if JOBQR = 'N'.
-C             For good performance when JOBQR = 'Q', LDWORK should be
-C             larger. Specifically, LDWORK >= 2*N + ( N + 1 )*NB, where
-C             NB is the optimal block size for the LAPACK Library
-C             routine DGEQP3.
-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     METHOD
-C
-C     The routine computes or uses a QR factorization with column
-C     pivoting of A,  A * P = Q * R,  with  R  defined above, and then
-C     finds the largest leading submatrix whose estimated condition
-C     number is less than 1/RCOND, taking the possible positive value of
-C     SVLMAX into account.  This is performed using the LAPACK
-C     incremental condition estimation scheme and a slightly modified
-C     rank decision test.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Nov. 1996.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Mar. 2005.
-C
-C    ******************************************************************
-C
-C     .. Parameters ..
-      INTEGER            IMAX, IMIN
-      PARAMETER          ( IMAX = 1, IMIN = 2 )
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER          JOBQR
-      INTEGER            INFO, LDA, LDWORK, M, N, RANK
-      DOUBLE PRECISION   RCOND, SVLMAX
-C     .. Array Arguments ..
-      INTEGER            JPVT( * )
-      DOUBLE PRECISION   A( LDA, * ), SVAL( 3 ), TAU( * ), DWORK( * )
-C     .. Local Scalars ..
-      LOGICAL            LJOBQR
-      INTEGER            I, ISMAX, ISMIN, MAXWRK, MINWRK, MN
-      DOUBLE PRECISION   C1, C2, S1, S2, SMAX, SMAXPR, SMIN, SMINPR
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DGEQP3, DLAIC1, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, INT, MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-      LJOBQR = LSAME( JOBQR, 'Q' )
-      MN = MIN( M, N )
-      ISMIN = 1
-      ISMAX = MN + 1
-      IF( LJOBQR ) THEN
-         MINWRK = 3*N + 1
-      ELSE
-         MINWRK = MAX( 1, 2*MN )
-      END IF
-      MAXWRK = MINWRK
-C
-C     Test the input scalar arguments.
-C
-      INFO = 0
-      IF( .NOT.LJOBQR .AND. .NOT.LSAME( JOBQR, 'N' ) ) THEN
-         INFO = -1
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
-         INFO = -5
-      ELSE IF( RCOND.LT.ZERO ) THEN
-         INFO = -7
-      ELSE IF( SVLMAX.LT.ZERO ) THEN
-         INFO = -8
-      ELSE IF( LDWORK.LT.MINWRK ) THEN
-         INFO = -13
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'MB03OD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible
-C
-      IF( MN.EQ.0 ) THEN
-         RANK = 0
-         SVAL(  1 ) = ZERO
-         SVAL(  2 ) = ZERO
-         SVAL(  3 ) = ZERO
-         DWORK( 1 ) = ONE
-         RETURN
-      END IF
-C
-      IF ( LJOBQR ) THEN
-C
-C        Compute QR factorization with column pivoting of A:
-C           A * P = Q * R
-C        Workspace need   3*N + 1;
-C                  prefer 2*N + (N+1)*NB.
-C        Details of Householder rotations stored in TAU.
-C
-         CALL DGEQP3( M, N, A, LDA, JPVT, TAU, DWORK, LDWORK, INFO )
-         MAXWRK = MAX( MAXWRK, INT( DWORK(1) ) )
-      END IF
-C
-C     Determine RANK using incremental condition estimation
-C
-      DWORK( ISMIN ) = ONE
-      DWORK( ISMAX ) = ONE
-      SMAX = ABS( A( 1, 1 ) )
-      SMIN = SMAX
-      IF( SMAX.EQ.ZERO .OR. SVLMAX*RCOND.GT.SMAX ) THEN
-         RANK = 0
-         SVAL( 1 ) = SMAX
-         SVAL( 2 ) = ZERO
-         SVAL( 3 ) = ZERO
-      ELSE
-         RANK = 1
-         SMINPR = SMIN
-C
-   10    CONTINUE
-         IF( RANK.LT.MN ) THEN
-            I = RANK + 1
-            CALL DLAIC1( IMIN, RANK, DWORK( ISMIN ), SMIN, A( 1, I ),
-     $                   A( I, I ), SMINPR, S1, C1 )
-            CALL DLAIC1( IMAX, RANK, DWORK( ISMAX ), SMAX, A( 1, I ),
-     $                   A( I, I ), SMAXPR, S2, C2 )
-C
-            IF( SVLMAX*RCOND.LE.SMAXPR ) THEN
-               IF( SVLMAX*RCOND.LE.SMINPR ) THEN
-                  IF( SMAXPR*RCOND.LE.SMINPR ) THEN
-                     DO 20 I = 1, RANK
-                        DWORK( ISMIN+I-1 ) = S1*DWORK( ISMIN+I-1 )
-                        DWORK( ISMAX+I-1 ) = S2*DWORK( ISMAX+I-1 )
-   20                CONTINUE
-                     DWORK( ISMIN+RANK ) = C1
-                     DWORK( ISMAX+RANK ) = C2
-                     SMIN = SMINPR
-                     SMAX = SMAXPR
-                     RANK = RANK + 1
-                     GO TO 10
-                  END IF
-               END IF
-            END IF
-         END IF
-         SVAL( 1 ) = SMAX
-         SVAL( 2 ) = SMIN
-         SVAL( 3 ) = SMINPR
-      END IF
-C
-      DWORK( 1 ) = MAXWRK
-      RETURN
-C *** Last line of MB03OD ***
-      END
--- a/extra/control-devel/src/MB03OY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,388 +0,0 @@
-      SUBROUTINE MB03OY( M, N, A, LDA, RCOND, SVLMAX, RANK, SVAL, JPVT,
-     $                   TAU, DWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a rank-revealing QR factorization of a real general
-C     M-by-N matrix  A,  which may be rank-deficient, and estimate its
-C     effective rank using incremental condition estimation.
-C
-C     The routine uses a truncated QR factorization with column pivoting
-C                                   [ R11 R12 ]
-C        A * P = Q * R,  where  R = [         ],
-C                                   [  0  R22 ]
-C     with R11 defined as the largest leading upper triangular submatrix
-C     whose estimated condition number is less than 1/RCOND.  The order
-C     of R11, RANK, is the effective rank of A.  Condition estimation is
-C     performed during the QR factorization process.  Matrix R22 is full
-C     (but of small norm), or empty.
-C
-C     MB03OY  does not perform any scaling of the matrix A.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrix A.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrix A.  N >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension
-C             ( LDA, N )
-C             On entry, the leading M-by-N part of this array must
-C             contain the given matrix A.
-C             On exit, the leading RANK-by-RANK upper triangular part
-C             of A contains the triangular factor R11, and the elements
-C             below the diagonal in the first  RANK  columns, with the
-C             array TAU, represent the orthogonal matrix Q as a product
-C             of  RANK  elementary reflectors.
-C             The remaining  N-RANK  columns contain the result of the
-C             QR factorization process used.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,M).
-C
-C     RCOND   (input) DOUBLE PRECISION
-C             RCOND is used to determine the effective rank of A, which
-C             is defined as the order of the largest leading triangular
-C             submatrix R11 in the QR factorization with pivoting of A,
-C             whose estimated condition number is less than 1/RCOND.
-C             0 <= RCOND <= 1.
-C             NOTE that when SVLMAX > 0, the estimated rank could be
-C             less than that defined above (see SVLMAX).
-C
-C     SVLMAX  (input) DOUBLE PRECISION
-C             If A is a submatrix of another matrix B, and the rank
-C             decision should be related to that matrix, then SVLMAX
-C             should be an estimate of the largest singular value of B
-C             (for instance, the Frobenius norm of B).  If this is not
-C             the case, the input value SVLMAX = 0 should work.
-C             SVLMAX >= 0.
-C
-C     RANK    (output) INTEGER
-C             The effective (estimated) rank of A, i.e., the order of
-C             the submatrix R11.
-C
-C     SVAL    (output) DOUBLE PRECISION array, dimension ( 3 )
-C             The estimates of some of the singular values of the
-C             triangular factor R:
-C             SVAL(1): largest singular value of R(1:RANK,1:RANK);
-C             SVAL(2): smallest singular value of R(1:RANK,1:RANK);
-C             SVAL(3): smallest singular value of R(1:RANK+1,1:RANK+1),
-C                      if RANK < MIN( M, N ), or of R(1:RANK,1:RANK),
-C                      otherwise.
-C             If the triangular factorization is a rank-revealing one
-C             (which will be the case if the leading columns were well-
-C             conditioned), then SVAL(1) will also be an estimate for
-C             the largest singular value of A, and SVAL(2) and SVAL(3)
-C             will be estimates for the RANK-th and (RANK+1)-st singular
-C             values of A, respectively.
-C             By examining these values, one can confirm that the rank
-C             is well defined with respect to the chosen value of RCOND.
-C             The ratio SVAL(1)/SVAL(2) is an estimate of the condition
-C             number of R(1:RANK,1:RANK).
-C
-C     JPVT    (output) INTEGER array, dimension ( N )
-C             If JPVT(i) = k, then the i-th column of A*P was the k-th
-C             column of A.
-C
-C     TAU     (output) DOUBLE PRECISION array, dimension ( MIN( M, N ) )
-C             The leading  RANK  elements of TAU contain the scalar
-C             factors of the elementary reflectors.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension ( 3*N-1 )
-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     METHOD
-C
-C     The routine computes a truncated QR factorization with column
-C     pivoting of A,  A * P = Q * R,  with  R  defined above, and,
-C     during this process, finds the largest leading submatrix whose
-C     estimated condition number is less than 1/RCOND, taking the
-C     possible positive value of SVLMAX into account.  This is performed
-C     using the LAPACK incremental condition estimation scheme and a
-C     slightly modified rank decision test.  The factorization process
-C     stops when  RANK  has been determined.
-C
-C     The matrix Q is represented as a product of elementary reflectors
-C
-C        Q = H(1) H(2) . . . H(k), where k = rank <= min(m,n).
-C
-C     Each H(i) has the form
-C
-C        H = I - tau * v * v'
-C
-C     where tau is a real scalar, and v is a real vector with
-C     v(1:i-1) = 0 and v(i) = 1; v(i+1:m) is stored on exit in
-C     A(i+1:m,i), and tau in TAU(i).
-C
-C     The matrix P is represented in jpvt as follows: If
-C        jpvt(j) = i
-C     then the jth column of P is the ith canonical unit vector.
-C
-C     REFERENCES
-C
-C     [1] Bischof, C.H. and P. Tang.
-C         Generalizing Incremental Condition Estimation.
-C         LAPACK Working Notes 32, Mathematics and Computer Science
-C         Division, Argonne National Laboratory, UT, CS-91-132,
-C         May 1991.
-C
-C     [2] Bischof, C.H. and P. Tang.
-C         Robust Incremental Condition Estimation.
-C         LAPACK Working Notes 33, Mathematics and Computer Science
-C         Division, Argonne National Laboratory, UT, CS-91-133,
-C         May 1991.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is backward stable.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1998.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Jan. 2009.
-C
-C     KEYWORDS
-C
-C     Eigenvalue problem, matrix operations, orthogonal transformation,
-C     singular values.
-C
-C    ******************************************************************
-C
-C     .. Parameters ..
-      INTEGER            IMAX, IMIN
-      PARAMETER          ( IMAX = 1, IMIN = 2 )
-      DOUBLE PRECISION   ZERO, ONE, P05
-      PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0, P05 = 0.05D0 )
-C     .. Scalar Arguments ..
-      INTEGER            INFO, LDA, M, N, RANK
-      DOUBLE PRECISION   RCOND, SVLMAX
-C     .. Array Arguments ..
-      INTEGER            JPVT( * )
-      DOUBLE PRECISION   A( LDA, * ), DWORK( * ), SVAL( 3 ), TAU( * )
-C     ..
-C     .. Local Scalars ..
-      INTEGER            I, ISMAX, ISMIN, ITEMP, J, MN, PVT
-      DOUBLE PRECISION   AII, C1, C2, S1, S2, SMAX, SMAXPR, SMIN,
-     $                   SMINPR, TEMP, TEMP2
-C     ..
-C     .. External Functions ..
-      INTEGER            IDAMAX
-      DOUBLE PRECISION   DNRM2
-      EXTERNAL           DNRM2, IDAMAX
-C     .. External Subroutines ..
-      EXTERNAL           DLAIC1, DLARF, DLARFG, DSCAL, DSWAP, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, MAX, MIN, SQRT
-C     ..
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO = 0
-      IF( M.LT.0 ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
-         INFO = -4
-      ELSE IF( RCOND.LT.ZERO .OR. RCOND.GT.ONE ) THEN
-         INFO = -5
-      ELSE IF( SVLMAX.LT.ZERO ) THEN
-         INFO = -6
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'MB03OY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      MN = MIN( M, N )
-      IF( MN.EQ.0 ) THEN
-         RANK = 0
-         SVAL( 1 ) = ZERO
-         SVAL( 2 ) = ZERO
-         SVAL( 3 ) = ZERO
-         RETURN
-      END IF
-C
-      ISMIN = 1
-      ISMAX = ISMIN + N
-C
-C     Initialize partial column norms and pivoting vector. The first n
-C     elements of DWORK store the exact column norms. The already used
-C     leading part is then overwritten by the condition estimator.
-C
-      DO 10 I = 1, N
-         DWORK( I ) = DNRM2( M, A( 1, I ), 1 )
-         DWORK( N+I ) = DWORK( I )
-         JPVT( I ) = I
-   10 CONTINUE
-C
-C     Compute factorization and determine RANK using incremental
-C     condition estimation.
-C
-      RANK = 0
-C
-   20 CONTINUE
-      IF( RANK.LT.MN ) THEN
-         I = RANK + 1
-C
-C        Determine ith pivot column and swap if necessary.
-C
-         PVT = ( I-1 ) + IDAMAX( N-I+1, DWORK( I ), 1 )
-C
-         IF( PVT.NE.I ) THEN
-            CALL DSWAP( M, A( 1, PVT ), 1, A( 1, I ), 1 )
-            ITEMP = JPVT( PVT )
-            JPVT( PVT ) = JPVT( I )
-            JPVT( I )   = ITEMP
-            DWORK( PVT )   = DWORK( I )
-            DWORK( N+PVT ) = DWORK( N+I )
-         END IF
-C
-C        Save A(I,I) and generate elementary reflector H(i).
-C
-         IF( I.LT.M ) THEN
-            AII = A( I, I )
-            CALL DLARFG( M-I+1, A( I, I ), A( I+1, I ), 1, TAU( I ) )
-         ELSE
-            TAU( M ) = ZERO
-         END IF
-C
-         IF( RANK.EQ.0 ) THEN
-C
-C           Initialize; exit if matrix is zero (RANK = 0).
-C
-            SMAX = ABS( A( 1, 1 ) )
-            IF ( SMAX.EQ.ZERO ) THEN
-               SVAL( 1 ) = ZERO
-               SVAL( 2 ) = ZERO
-               SVAL( 3 ) = ZERO
-               RETURN
-            END IF
-            SMIN = SMAX
-            SMAXPR = SMAX
-            SMINPR = SMIN
-            C1 = ONE
-            C2 = ONE
-         ELSE
-C
-C           One step of incremental condition estimation.
-C
-            CALL DLAIC1( IMIN, RANK, DWORK( ISMIN ), SMIN, A( 1, I ),
-     $                   A( I, I ), SMINPR, S1, C1 )
-            CALL DLAIC1( IMAX, RANK, DWORK( ISMAX ), SMAX, A( 1, I ),
-     $                   A( I, I ), SMAXPR, S2, C2 )
-         END IF
-C
-         IF( SVLMAX*RCOND.LE.SMAXPR ) THEN
-            IF( SVLMAX*RCOND.LE.SMINPR ) THEN
-               IF( SMAXPR*RCOND.LE.SMINPR ) THEN
-C
-C                 Continue factorization, as rank is at least RANK.
-C
-                  IF( I.LT.N ) THEN
-C
-C                    Apply H(i) to A(i:m,i+1:n) from the left.
-C
-                     AII = A( I, I )
-                     A( I, I ) = ONE
-                     CALL DLARF( 'Left', M-I+1, N-I, A( I, I ), 1,
-     $                           TAU( I ), A( I, I+1 ), LDA,
-     $                           DWORK( 2*N+1 ) )
-                     A( I, I ) = AII
-                  END IF
-C
-C                 Update partial column norms.
-C
-                  DO 30 J = I + 1, N
-                     IF( DWORK( J ).NE.ZERO ) THEN
-                        TEMP = ONE -
-     $                            ( ABS( A( I, J ) ) / DWORK( J ) )**2
-                        TEMP = MAX( TEMP, ZERO )
-                        TEMP2 = ONE + P05*TEMP*
-     $                            ( DWORK( J ) / DWORK( N+J ) )**2
-                        IF( TEMP2.EQ.ONE ) THEN
-                           IF( M-I.GT.0 ) THEN
-                              DWORK( J ) = DNRM2( M-I, A( I+1, J ), 1 )
-                              DWORK( N+J ) = DWORK( J )
-                           ELSE
-                              DWORK( J )   = ZERO
-                              DWORK( N+J ) = ZERO
-                           END IF
-                        ELSE
-                           DWORK( J ) = DWORK( J )*SQRT( TEMP )
-                        END IF
-                     END IF
-   30             CONTINUE
-C
-                  DO 40 I = 1, RANK
-                     DWORK( ISMIN+I-1 ) = S1*DWORK( ISMIN+I-1 )
-                     DWORK( ISMAX+I-1 ) = S2*DWORK( ISMAX+I-1 )
-   40             CONTINUE
-C
-                  DWORK( ISMIN+RANK ) = C1
-                  DWORK( ISMAX+RANK ) = C2
-                  SMIN = SMINPR
-                  SMAX = SMAXPR
-                  RANK = RANK + 1
-                  GO TO 20
-               END IF
-            END IF
-         END IF
-      END IF
-C
-C     Restore the changed part of the (RANK+1)-th column and set SVAL.
-C
-      IF ( RANK.LT.N ) THEN
-         IF ( I.LT.M ) THEN
-            CALL DSCAL( M-I, -A( I, I )*TAU( I ), A( I+1, I ), 1 )
-            A( I, I ) = AII
-         END IF
-      END IF
-      IF ( RANK.EQ.0 ) THEN
-         SMIN = ZERO
-         SMINPR = ZERO
-      END IF
-      SVAL( 1 ) = SMAX
-      SVAL( 2 ) = SMIN
-      SVAL( 3 ) = SMINPR
-C
-      RETURN
-C *** Last line of MB03OY ***
-      END
--- a/extra/control-devel/src/MB03PY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,392 +0,0 @@
-      SUBROUTINE MB03PY( M, N, A, LDA, RCOND, SVLMAX, RANK, SVAL, JPVT,
-     $                   TAU, DWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a rank-revealing RQ factorization of a real general
-C     M-by-N matrix  A,  which may be rank-deficient, and estimate its
-C     effective rank using incremental condition estimation.
-C
-C     The routine uses a truncated RQ factorization with row pivoting:
-C                                   [ R11 R12 ]
-C        P * A = R * Q,  where  R = [         ],
-C                                   [  0  R22 ]
-C     with R22 defined as the largest trailing upper triangular
-C     submatrix whose estimated condition number is less than 1/RCOND.
-C     The order of R22, RANK, is the effective rank of A.  Condition
-C     estimation is performed during the RQ factorization process.
-C     Matrix R11 is full (but of small norm), or empty.
-C
-C     MB03PY  does not perform any scaling of the matrix A.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrix A.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrix A.  N >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension
-C             ( LDA, N )
-C             On entry, the leading M-by-N part of this array must
-C             contain the given matrix A.
-C             On exit, the upper triangle of the subarray
-C             A(M-RANK+1:M,N-RANK+1:N) contains the RANK-by-RANK upper
-C             triangular matrix R22;  the remaining elements in the last
-C             RANK  rows, with the array TAU, represent the orthogonal
-C             matrix Q as a product of  RANK  elementary reflectors
-C             (see METHOD).  The first  M-RANK  rows contain the result
-C             of the RQ factorization process used.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,M).
-C
-C     RCOND   (input) DOUBLE PRECISION
-C             RCOND is used to determine the effective rank of A, which
-C             is defined as the order of the largest trailing triangular
-C             submatrix R22 in the RQ factorization with pivoting of A,
-C             whose estimated condition number is less than 1/RCOND.
-C             0 <= RCOND <= 1.
-C             NOTE that when SVLMAX > 0, the estimated rank could be
-C             less than that defined above (see SVLMAX).
-C
-C     SVLMAX  (input) DOUBLE PRECISION
-C             If A is a submatrix of another matrix B, and the rank
-C             decision should be related to that matrix, then SVLMAX
-C             should be an estimate of the largest singular value of B
-C             (for instance, the Frobenius norm of B).  If this is not
-C             the case, the input value SVLMAX = 0 should work.
-C             SVLMAX >= 0.
-C
-C     RANK    (output) INTEGER
-C             The effective (estimated) rank of A, i.e., the order of
-C             the submatrix R22.
-C
-C     SVAL    (output) DOUBLE PRECISION array, dimension ( 3 )
-C             The estimates of some of the singular values of the
-C             triangular factor R:
-C             SVAL(1): largest singular value of
-C                      R(M-RANK+1:M,N-RANK+1:N);
-C             SVAL(2): smallest singular value of
-C                      R(M-RANK+1:M,N-RANK+1:N);
-C             SVAL(3): smallest singular value of R(M-RANK:M,N-RANK:N),
-C                      if RANK < MIN( M, N ), or of
-C                      R(M-RANK+1:M,N-RANK+1:N), otherwise.
-C             If the triangular factorization is a rank-revealing one
-C             (which will be the case if the trailing rows were well-
-C             conditioned), then SVAL(1) will also be an estimate for
-C             the largest singular value of A, and SVAL(2) and SVAL(3)
-C             will be estimates for the RANK-th and (RANK+1)-st singular
-C             values of A, respectively.
-C             By examining these values, one can confirm that the rank
-C             is well defined with respect to the chosen value of RCOND.
-C             The ratio SVAL(1)/SVAL(2) is an estimate of the condition
-C             number of R(M-RANK+1:M,N-RANK+1:N).
-C
-C     JPVT    (output) INTEGER array, dimension ( M )
-C             If JPVT(i) = k, then the i-th row of P*A was the k-th row
-C             of A.
-C
-C     TAU     (output) DOUBLE PRECISION array, dimension ( MIN( M, N ) )
-C             The trailing  RANK  elements of TAU contain the scalar
-C             factors of the elementary reflectors.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension ( 3*M-1 )
-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     METHOD
-C
-C     The routine computes a truncated RQ factorization with row
-C     pivoting of A,  P * A = R * Q,  with  R  defined above, and,
-C     during this process, finds the largest trailing submatrix whose
-C     estimated condition number is less than 1/RCOND, taking the
-C     possible positive value of SVLMAX into account.  This is performed
-C     using an adaptation of the LAPACK incremental condition estimation
-C     scheme and a slightly modified rank decision test.  The
-C     factorization process stops when  RANK  has been determined.
-C
-C     The matrix Q is represented as a product of elementary reflectors
-C
-C        Q = H(k-rank+1) H(k-rank+2) . . . H(k), where k = min(m,n).
-C
-C     Each H(i) has the form
-C
-C        H = I - tau * v * v'
-C
-C     where tau is a real scalar, and v is a real vector with
-C     v(n-k+i+1:n) = 0 and v(n-k+i) = 1; v(1:n-k+i-1) is stored on exit
-C     in A(m-k+i,1:n-k+i-1), and tau in TAU(i).
-C
-C     The matrix P is represented in jpvt as follows: If
-C        jpvt(j) = i
-C     then the jth row of P is the ith canonical unit vector.
-C
-C     REFERENCES
-C
-C     [1] Bischof, C.H. and P. Tang.
-C         Generalizing Incremental Condition Estimation.
-C         LAPACK Working Notes 32, Mathematics and Computer Science
-C         Division, Argonne National Laboratory, UT, CS-91-132,
-C         May 1991.
-C
-C     [2] Bischof, C.H. and P. Tang.
-C         Robust Incremental Condition Estimation.
-C         LAPACK Working Notes 33, Mathematics and Computer Science
-C         Division, Argonne National Laboratory, UT, CS-91-133,
-C         May 1991.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is backward stable.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1998.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2001,
-C     Jan. 2009.
-C
-C     KEYWORDS
-C
-C     Eigenvalue problem, matrix operations, orthogonal transformation,
-C     singular values.
-C
-C    ******************************************************************
-C
-C     .. Parameters ..
-      INTEGER            IMAX, IMIN
-      PARAMETER          ( IMAX = 1, IMIN = 2 )
-      DOUBLE PRECISION   ZERO, ONE, P05
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, P05 = 0.05D+0 )
-C     .. Scalar Arguments ..
-      INTEGER            INFO, LDA, M, N, RANK
-      DOUBLE PRECISION   RCOND, SVLMAX
-C     .. Array Arguments ..
-      INTEGER            JPVT( * )
-      DOUBLE PRECISION   A( LDA, * ), DWORK( * ), SVAL( 3 ), TAU( * )
-C     .. Local Scalars ..
-      INTEGER            I, ISMAX, ISMIN, ITEMP, J, JWORK, K, MKI, NKI,
-     $                   PVT
-      DOUBLE PRECISION   AII, C1, C2, S1, S2, SMAX, SMAXPR, SMIN,
-     $                   SMINPR, TEMP, TEMP2
-C     ..
-C     .. External Functions ..
-      INTEGER            IDAMAX
-      DOUBLE PRECISION   DNRM2
-      EXTERNAL           DNRM2, IDAMAX
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DCOPY, DLAIC1, DLARF, DLARFG, DSCAL, DSWAP,
-     $                   XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, MAX, MIN, SQRT
-C     ..
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO = 0
-      IF( M.LT.0 ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
-         INFO = -4
-      ELSE IF( RCOND.LT.ZERO .OR. RCOND.GT.ONE ) THEN
-         INFO = -5
-      ELSE IF( SVLMAX.LT.ZERO ) THEN
-         INFO = -6
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'MB03PY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      K = MIN( M, N )
-      IF( K.EQ.0 ) THEN
-         RANK = 0
-         SVAL( 1 ) = ZERO
-         SVAL( 2 ) = ZERO
-         SVAL( 3 ) = ZERO
-         RETURN
-      END IF
-C
-      ISMIN = M
-      ISMAX = ISMIN + M
-      JWORK = ISMAX + 1
-C
-C     Initialize partial row norms and pivoting vector. The first m
-C     elements of DWORK store the exact row norms. The already used
-C     trailing part is then overwritten by the condition estimator.
-C
-      DO 10 I = 1, M
-         DWORK( I ) = DNRM2( N, A( I, 1 ), LDA )
-         DWORK( M+I ) = DWORK( I )
-         JPVT( I ) = I
-   10 CONTINUE
-C
-C     Compute factorization and determine RANK using incremental
-C     condition estimation.
-C
-      RANK = 0
-C
-   20 CONTINUE
-      IF( RANK.LT.K ) THEN
-         I = K - RANK
-C
-C        Determine ith pivot row and swap if necessary.
-C
-         MKI = M - RANK
-         NKI = N - RANK
-         PVT = IDAMAX( MKI, DWORK, 1 )
-C
-         IF( PVT.NE.MKI ) THEN
-            CALL DSWAP( N, A( PVT, 1 ), LDA, A( MKI, 1 ), LDA )
-            ITEMP = JPVT( PVT )
-            JPVT( PVT ) = JPVT( MKI )
-            JPVT( MKI ) = ITEMP
-            DWORK( PVT )   = DWORK( MKI )
-            DWORK( M+PVT ) = DWORK( M+MKI )
-         END IF
-C
-         IF( NKI.GT.1 ) THEN
-C
-C           Save A(m-k+i,n-k+i) and generate elementary reflector H(i)
-C           to annihilate A(m-k+i,1:n-k+i-1), k = min(m,n).
-C
-            AII = A( MKI, NKI )
-            CALL DLARFG( NKI, A( MKI, NKI ), A( MKI, 1 ), LDA, TAU( I )
-     $                 )
-         END IF
-C
-         IF( RANK.EQ.0 ) THEN
-C
-C           Initialize; exit if matrix is zero (RANK = 0).
-C
-            SMAX = ABS( A( M, N ) )
-            IF ( SMAX.EQ.ZERO ) THEN
-               SVAL( 1 ) = ZERO
-               SVAL( 2 ) = ZERO
-               SVAL( 3 ) = ZERO
-               RETURN
-            END IF
-            SMIN = SMAX
-            SMAXPR = SMAX
-            SMINPR = SMIN
-            C1 = ONE
-            C2 = ONE
-         ELSE
-C
-C           One step of incremental condition estimation.
-C
-            CALL DCOPY ( RANK, A( MKI, NKI+1 ), LDA, DWORK( JWORK ), 1 )
-            CALL DLAIC1( IMIN, RANK, DWORK( ISMIN ), SMIN,
-     $                   DWORK( JWORK ), A( MKI, NKI ), SMINPR, S1, C1 )
-            CALL DLAIC1( IMAX, RANK, DWORK( ISMAX ), SMAX,
-     $                   DWORK( JWORK ), A( MKI, NKI ), SMAXPR, S2, C2 )
-         END IF
-C
-         IF( SVLMAX*RCOND.LE.SMAXPR ) THEN
-            IF( SVLMAX*RCOND.LE.SMINPR ) THEN
-               IF( SMAXPR*RCOND.LE.SMINPR ) THEN
-C
-                  IF( MKI.GT.1 ) THEN
-C
-C                    Continue factorization, as rank is at least RANK.
-C                    Apply H(i) to A(1:m-k+i-1,1:n-k+i) from the right.
-C
-                     AII = A( MKI, NKI )
-                     A( MKI, NKI ) = ONE
-                     CALL DLARF( 'Right', MKI-1, NKI, A( MKI, 1 ), LDA,
-     $                           TAU( I ), A, LDA, DWORK( JWORK ) )
-                     A( MKI, NKI ) = AII
-C
-C                    Update partial row norms.
-C
-                     DO 30 J = 1, MKI - 1
-                        IF( DWORK( J ).NE.ZERO ) THEN
-                           TEMP  = ONE -
-     $                             ( ABS( A( J, NKI ) )/DWORK( J ) )**2
-                           TEMP  = MAX( TEMP, ZERO )
-                           TEMP2 = ONE + P05*TEMP*
-     $                                 ( DWORK( J ) / DWORK( M+J ) )**2
-                           IF( TEMP2.EQ.ONE ) THEN
-                              DWORK( J )   = DNRM2( NKI-1, A( J, 1 ),
-     $                                              LDA )
-                              DWORK( M+J ) = DWORK( J )
-                           ELSE
-                              DWORK( J ) = DWORK( J )*SQRT( TEMP )
-                           END IF
-                        END IF
-   30                CONTINUE
-C
-                  END IF
-C
-                  DO 40 I = 1, RANK
-                     DWORK( ISMIN+I-1 ) = S1*DWORK( ISMIN+I-1 )
-                     DWORK( ISMAX+I-1 ) = S2*DWORK( ISMAX+I-1 )
-   40             CONTINUE
-C
-                  IF( RANK.GT.0 ) THEN
-                     ISMIN = ISMIN - 1
-                     ISMAX = ISMAX - 1
-                  END IF
-                  DWORK( ISMIN ) = C1
-                  DWORK( ISMAX ) = C2
-                  SMIN = SMINPR
-                  SMAX = SMAXPR
-                  RANK = RANK + 1
-                  GO TO 20
-               END IF
-            END IF
-         END IF
-      END IF
-C
-C     Restore the changed part of the (M-RANK)-th row and set SVAL.
-C
-      IF ( RANK.LT.K .AND. NKI.GT.1 ) THEN
-         CALL DSCAL( NKI-1, -A( MKI, NKI )*TAU( I ), A( MKI, 1 ), LDA )
-         A( MKI, NKI ) = AII
-      END IF
-      SVAL( 1 ) = SMAX
-      SVAL( 2 ) = SMIN
-      SVAL( 3 ) = SMINPR
-C
-      RETURN
-C *** Last line of MB03PY ***
-      END
--- a/extra/control-devel/src/MB03QD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,316 +0,0 @@
-      SUBROUTINE MB03QD( DICO, STDOM, JOBU, N, NLOW, NSUP, ALPHA,
-     $                   A, LDA, U, LDU, NDIM, DWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To reorder the diagonal blocks of a principal submatrix of an
-C     upper quasi-triangular matrix A together with their eigenvalues by
-C     constructing an orthogonal similarity transformation UT.
-C     After reordering, the leading block of the selected submatrix of A
-C     has eigenvalues in a suitably defined domain of interest, usually
-C     related to stability/instability in a continuous- or discrete-time
-C     sense.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the spectrum separation to be
-C             performed as follows:
-C             = 'C':  continuous-time sense;
-C             = 'D':  discrete-time sense.
-C
-C     STDOM   CHARACTER*1
-C             Specifies whether the domain of interest is of stability
-C             type (left part of complex plane or inside of a circle)
-C             or of instability type (right part of complex plane or
-C             outside of a circle) as follows:
-C             = 'S':  stability type domain;
-C             = 'U':  instability type domain.
-C
-C     JOBU    CHARACTER*1
-C             Indicates how the performed orthogonal transformations UT
-C             are accumulated, as follows:
-C             = 'I':  U is initialized to the unit matrix and the matrix
-C                     UT is returned in U;
-C             = 'U':  the given matrix U is updated and the matrix U*UT
-C                     is returned in U.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A and U.  N >= 1.
-C
-C     NLOW,   (input) INTEGER
-C     NSUP    NLOW and NSUP specify the boundary indices for the rows
-C             and columns of the principal submatrix of A whose diagonal
-C             blocks are to be reordered.  1 <= NLOW <= NSUP <= N.
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             The boundary of the domain of interest for the eigenvalues
-C             of A. If DICO = 'C', ALPHA is the boundary value for the
-C             real parts of eigenvalues, while for DICO = 'D',
-C             ALPHA >= 0 represents the boundary value for the moduli of
-C             eigenvalues.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain a matrix in a real Schur form whose 1-by-1 and
-C             2-by-2 diagonal blocks between positions NLOW and NSUP
-C             are to be reordered.
-C             On exit, the leading N-by-N part contains the ordered
-C             real Schur matrix UT' * A * UT with the elements below the
-C             first subdiagonal set to zero.
-C             The leading NDIM-by-NDIM part of the principal submatrix
-C             D = A(NLOW:NSUP,NLOW:NSUP) has eigenvalues in the domain
-C             of interest and the trailing part of this submatrix has
-C             eigenvalues outside the domain of interest.
-C             The domain of interest for lambda(D), the eigenvalues of
-C             D, is defined by the parameters ALPHA, DICO and STDOM as
-C             follows:
-C               For DICO = 'C':
-C                  Real(lambda(D)) < ALPHA if STDOM = 'S';
-C                  Real(lambda(D)) > ALPHA if STDOM = 'U'.
-C               For DICO = 'D':
-C                  Abs(lambda(D)) < ALPHA if STDOM = 'S';
-C                  Abs(lambda(D)) > ALPHA if STDOM = 'U'.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= N.
-C
-C     U       (input/output) DOUBLE PRECISION array, dimension (LDU,N)
-C             On entry with JOBU = 'U', the leading N-by-N part of this
-C             array must contain a transformation matrix (e.g. from a
-C             previous call to this routine).
-C             On exit, if JOBU = 'U', the leading N-by-N part of this
-C             array contains the product of the input matrix U and the
-C             orthogonal matrix UT used to reorder the diagonal blocks
-C             of A.
-C             On exit, if JOBU = 'I', the leading N-by-N part of this
-C             array contains the matrix UT of the performed orthogonal
-C             transformations.
-C             Array U need not be set on entry if JOBU = 'I'.
-C
-C     LDU     INTEGER
-C             The leading dimension of array U.  LDU >= N.
-C
-C     NDIM    (output) INTEGER
-C             The number of eigenvalues of the selected principal
-C             submatrix lying inside the domain of interest.
-C             If NLOW = 1, NDIM is also the dimension of the invariant
-C             subspace corresponding to the eigenvalues of the leading
-C             NDIM-by-NDIM submatrix. In this case, if U is the
-C             orthogonal transformation matrix used to compute and
-C             reorder the real Schur form of A, its first NDIM columns
-C             form an orthonormal basis for the above invariant
-C             subspace.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (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:  A(NLOW,NLOW-1) is nonzero, i.e. A(NLOW,NLOW) is not
-C                   the leading element of a 1-by-1 or 2-by-2 diagonal
-C                   block of A, or A(NSUP+1,NSUP) is nonzero, i.e.
-C                   A(NSUP,NSUP) is not the bottom element of a 1-by-1
-C                   or 2-by-2 diagonal block of A;
-C             = 2:  two adjacent blocks are too close to swap (the
-C                   problem is very ill-conditioned).
-C
-C     METHOD
-C
-C     Given an upper quasi-triangular matrix A with 1-by-1 or 2-by-2
-C     diagonal blocks, the routine reorders its diagonal blocks along
-C     with its eigenvalues by performing an orthogonal similarity
-C     transformation UT' * A * UT. The column transformation UT is also
-C     performed on the given (initial) transformation U (resulted from
-C     a possible previous step or initialized as the identity matrix).
-C     After reordering, the eigenvalues inside the region specified by
-C     the parameters ALPHA, DICO and STDOM appear at the top of
-C     the selected diagonal block between positions NLOW and NSUP.
-C     In other words, lambda(A(NLOW:NSUP,NLOW:NSUP)) are ordered such
-C     that lambda(A(NLOW:NLOW+NDIM-1,NLOW:NLOW+NDIM-1)) are inside and
-C     lambda(A(NLOW+NDIM:NSUP,NLOW+NDIM:NSUP)) are outside the domain
-C     of interest. If NLOW = 1, the first NDIM columns of U*UT span the
-C     corresponding invariant subspace of A.
-C
-C     REFERENCES
-C
-C     [1] Stewart, G.W.
-C         HQR3 and EXCHQZ: FORTRAN subroutines for calculating and
-C         ordering the eigenvalues of a real upper Hessenberg matrix.
-C         ACM TOMS, 2, pp. 275-280, 1976.
-C
-C     NUMERICAL ASPECTS
-C                                         3
-C     The algorithm requires less than 4*N  operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center, DLR Oberpfaffenhofen,
-C     April 1998. Based on the RASP routine SEOR1.
-C
-C     KEYWORDS
-C
-C     Eigenvalues, invariant subspace, orthogonal transformation, real
-C     Schur form, similarity transformation.
-C
-C    ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION ONE, ZERO
-      PARAMETER        ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER        DICO, JOBU, STDOM
-      INTEGER          INFO, LDA, LDU, N, NDIM, NLOW, NSUP
-      DOUBLE PRECISION ALPHA
-C     .. Array Arguments ..
-      DOUBLE PRECISION A(LDA,*), DWORK(*), U(LDU,*)
-C     .. Local Scalars ..
-      LOGICAL          DISCR, LSTDOM
-      INTEGER          IB, L, LM1, NUP
-      DOUBLE PRECISION E1, E2, TLAMBD
-C     .. External Functions ..
-      LOGICAL          LSAME
-      DOUBLE PRECISION DLAPY2
-      EXTERNAL         DLAPY2, LSAME
-C     .. External Subroutines ..
-      EXTERNAL         DLASET, DTREXC, MB03QY, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC        ABS
-C     .. Executable Statements ..
-C
-      INFO = 0
-      DISCR = LSAME( DICO, 'D' )
-      LSTDOM = LSAME( STDOM, 'S' )
-C
-C     Check input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( LSTDOM .OR. LSAME( STDOM, 'U' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( LSAME( JOBU, 'I' ) .OR.
-     $                 LSAME( JOBU, 'U' ) ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.1 ) THEN
-         INFO = -4
-      ELSE IF( NLOW.LT.1 ) THEN
-         INFO = -5
-      ELSE IF( NLOW.GT.NSUP .OR. NSUP.GT.N ) THEN
-         INFO = -6
-      ELSE IF( DISCR .AND. ALPHA.LT.ZERO ) THEN
-         INFO = -7
-      ELSE IF( LDA.LT.N ) THEN
-         INFO = -9
-      ELSE IF( LDU.LT.N ) THEN
-         INFO = -11
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB03QD', -INFO )
-         RETURN
-      END IF
-C
-      IF( NLOW.GT.1 ) THEN
-         IF( A(NLOW,NLOW-1).NE.ZERO ) INFO = 1
-      END IF
-      IF( NSUP.LT.N ) THEN
-         IF( A(NSUP+1,NSUP).NE.ZERO ) INFO = 1
-      END IF
-      IF( INFO.NE.0 )
-     $   RETURN
-C
-C     Initialize U with an identity matrix if necessary.
-C
-      IF( LSAME( JOBU, 'I' ) )
-     $   CALL DLASET( 'Full', N, N, ZERO, ONE, U, LDU )
-C
-      NDIM = 0
-      L = NSUP
-      NUP = NSUP
-C
-C     NUP is the minimal value such that the submatrix A(i,j) with
-C     NUP+1 <= i,j <= NSUP contains no eigenvalues inside the domain of
-C     interest. L is such that all the eigenvalues of the submatrix
-C     A(i,j) with L+1 <= i,j <= NUP lie inside the domain of interest.
-C
-C     WHILE( L >= NLOW ) DO
-C
-   10 IF( L.GE.NLOW ) THEN
-         IB = 1
-         IF( L.GT.NLOW ) THEN
-            LM1 = L - 1
-            IF( A(L,LM1).NE.ZERO ) THEN
-               CALL MB03QY( N, LM1, A, LDA, U, LDU, E1, E2, INFO )
-               IF( A(L,LM1).NE.ZERO ) IB = 2
-            END IF
-         END IF
-         IF( DISCR ) THEN
-            IF( IB.EQ.1 ) THEN
-               TLAMBD = ABS( A(L,L) )
-            ELSE
-               TLAMBD = DLAPY2( E1, E2 )
-            END IF
-         ELSE
-            IF( IB.EQ.1 ) THEN
-               TLAMBD = A(L,L)
-            ELSE
-               TLAMBD = E1
-            END IF
-         END IF
-         IF( (      LSTDOM .AND. TLAMBD.LT.ALPHA ) .OR.
-     $       ( .NOT.LSTDOM .AND. TLAMBD.GT.ALPHA ) ) THEN
-            NDIM = NDIM + IB
-            L = L - IB
-         ELSE
-            IF( NDIM.NE.0 ) THEN
-               CALL DTREXC( 'V', N, A, LDA, U, LDU, L, NUP, DWORK,
-     $                      INFO )
-               IF( INFO.NE.0 ) THEN
-                  INFO = 2
-                  RETURN
-               END IF
-               NUP = NUP - 1
-               L = L - 1
-            ELSE
-               NUP = NUP - IB
-               L = L - IB
-            END IF
-         END IF
-         GO TO 10
-      END IF
-C
-C     END WHILE 10
-C
-      RETURN
-C *** Last line of MB03QD ***
-      END
--- a/extra/control-devel/src/MB03QX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,122 +0,0 @@
-      SUBROUTINE MB03QX( N, T, LDT, WR, WI, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the eigenvalues of an upper quasi-triangular matrix.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix T.  N >= 0.
-C
-C     T       (input) DOUBLE PRECISION array, dimension(LDT,N)
-C             The upper quasi-triangular matrix T.
-C
-C     LDT     INTEGER
-C             The leading dimension of the array T.  LDT >= max(1,N).
-C
-C     WR, WI  (output) DOUBLE PRECISION arrays, dimension (N)
-C             The real and imaginary parts, respectively, of the
-C             eigenvalues of T. The eigenvalues are stored in the same
-C             order as on the diagonal of T. If T(i:i+1,i:i+1) is a
-C             2-by-2 diagonal block with complex conjugated eigenvalues
-C             then WI(i) > 0 and WI(i+1) = -WI(i).
-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     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center, DLR Oberpfaffenhofen,
-C     March 1998. Based on the RASP routine SEIG.
-C
-C     ******************************************************************
-C     .. Parameters ..
-      DOUBLE PRECISION ZERO
-      PARAMETER        ( ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER          INFO, LDT, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION T(LDT, *), WI(*), WR(*)
-C     .. Local Scalars ..
-      INTEGER          I, I1, INEXT
-      DOUBLE PRECISION A11, A12, A21, A22, CS, SN
-C     .. External Subroutines ..
-      EXTERNAL         DLANV2, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC        MAX
-C     .. Executable Statements ..
-C
-      INFO = 0
-C
-C     Test the input scalar arguments.
-C
-      IF( N.LT.0 ) THEN
-         INFO = -1
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -3
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB03QX', -INFO )
-         RETURN
-      END IF
-C
-      INEXT = 1
-      DO 10 I = 1, N
-         IF( I.LT.INEXT )
-     $      GO TO 10
-         IF( I.NE.N ) THEN
-            IF( T(I+1,I).NE.ZERO ) THEN
-C
-C              A pair of eigenvalues.
-C
-               INEXT = I + 2
-               I1 = I + 1
-               A11 = T(I,I)
-               A12 = T(I,I1)
-               A21 = T(I1,I)
-               A22 = T(I1,I1)
-               CALL DLANV2( A11, A12, A21, A22, WR(I), WI(I), WR(I1),
-     $                      WI(I1), CS, SN )
-               GO TO 10
-            END IF
-         END IF
-C
-C        Simple eigenvalue.
-C
-         INEXT = I + 1
-         WR(I) = T(I,I)
-         WI(I) = ZERO
-   10 CONTINUE
-C
-      RETURN
-C *** Last line of MB03QX ***
-      END
--- a/extra/control-devel/src/MB03QY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,164 +0,0 @@
-      SUBROUTINE MB03QY( N, L, A, LDA, U, LDU, E1, E2, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the eigenvalues of a selected 2-by-2 diagonal block
-C     of an upper quasi-triangular matrix, to reduce the selected block
-C     to the standard form and to split the block in the case of real
-C     eigenvalues by constructing an orthogonal transformation UT.
-C     This transformation is applied to A (by similarity) and to
-C     another matrix U from the right.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A and UT.  N >= 2.
-C
-C     L       (input) INTEGER
-C             Specifies the position of the block.  1 <= L < N.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the upper quasi-triangular matrix A whose
-C             selected 2-by-2 diagonal block is to be processed.
-C             On exit, the leading N-by-N part of this array contains
-C             the upper quasi-triangular matrix A after its selected
-C             block has been splitt and/or put in the LAPACK standard
-C             form.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= N.
-C
-C     U       (input/output) DOUBLE PRECISION array, dimension (LDU,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain a transformation matrix U.
-C             On exit, the leading N-by-N part of this array contains
-C             U*UT, where UT is the transformation matrix used to
-C             split and/or standardize the selected block.
-C
-C     LDU     INTEGER
-C             The leading dimension of array U.  LDU >= N.
-C
-C     E1, E2  (output) DOUBLE PRECISION
-C             E1 and E2 contain either the real eigenvalues or the real
-C             and positive imaginary parts, respectively, of the complex
-C             eigenvalues of the selected 2-by-2 diagonal block of A.
-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     METHOD
-C
-C     Let A1 = ( A(L,L)    A(L,L+1)   )
-C              ( A(L+1,L)  A(L+1,L+1) )
-C     be the specified 2-by-2 diagonal block of matrix A.
-C     If the eigenvalues of A1 are complex, then they are computed and
-C     stored in E1 and E2, where the real part is stored in E1 and the
-C     positive imaginary part in E2. The 2-by-2 block is reduced if
-C     necessary to the standard form, such that A(L,L) = A(L+1,L+1), and
-C     A(L,L+1) and A(L+1,L) have oposite signs. If the eigenvalues are
-C     real, the 2-by-2 block is reduced to an upper triangular form such
-C     that ABS(A(L,L)) >= ABS(A(L+1,L+1)).
-C     In both cases, an orthogonal rotation U1' is constructed such that
-C     U1'*A1*U1 has the appropriate form. Let UT be an extension of U1
-C     to an N-by-N orthogonal matrix, using identity submatrices. Then A
-C     is replaced by UT'*A*UT and the contents of array U is U * UT.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center, DLR Oberpfaffenhofen,
-C     March 1998. Based on the RASP routine SPLITB.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Eigenvalues, orthogonal transformation, real Schur form,
-C     similarity transformation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION ZERO
-      PARAMETER        ( ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER          INFO, L, LDA, LDU, N
-      DOUBLE PRECISION E1, E2
-C     .. Array Arguments ..
-      DOUBLE PRECISION A(LDA,*), U(LDU,*)
-C     .. Local Scalars ..
-      INTEGER          L1
-      DOUBLE PRECISION EW1, EW2, CS, SN
-C     .. External Subroutines ..
-      EXTERNAL         DLANV2, DROT, XERBLA
-C     .. Executable Statements ..
-C
-      INFO = 0
-C
-C     Test the input scalar arguments.
-C
-      IF( N.LT.2 ) THEN
-         INFO = -1
-      ELSE IF( L.LT.1 .OR. L.GE.N ) THEN
-         INFO = -2
-      ELSE IF( LDA.LT.N ) THEN
-         INFO = -4
-      ELSE IF( LDU.LT.N ) THEN
-         INFO = -6
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB03QY', -INFO )
-         RETURN
-      END IF
-C
-C     Compute the eigenvalues and the elements of the Givens
-C     transformation.
-C
-      L1 = L + 1
-      CALL DLANV2( A(L,L), A(L,L1), A(L1,L), A(L1,L1), E1, E2,
-     $             EW1, EW2, CS, SN )
-      IF( E2.EQ.ZERO ) E2 = EW1
-C
-C     Apply the transformation to A.
-C
-      IF( L1.LT.N )
-     $   CALL DROT( N-L1, A(L,L1+1), LDA, A(L1,L1+1), LDA, CS, SN )
-      CALL DROT( L-1, A(1,L), 1, A(1,L1), 1, CS, SN )
-C
-C     Accumulate the transformation in U.
-C
-      CALL DROT( N, U(1,L), 1, U(1,L1), 1, CS, SN )
-C
-      RETURN
-C *** Last line of MB03QY ***
-      END
--- a/extra/control-devel/src/MB03UD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,318 +0,0 @@
-      SUBROUTINE MB03UD( JOBQ, JOBP, N, A, LDA, Q, LDQ, SV, 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 compute all, or part, of the singular value decomposition of a
-C     real upper triangular matrix.
-C
-C     The N-by-N upper triangular matrix A is factored as  A = Q*S*P',
-C     where Q and P are N-by-N orthogonal matrices and S is an
-C     N-by-N diagonal matrix with non-negative diagonal elements,
-C     SV(1), SV(2), ..., SV(N), ordered such that
-C
-C        SV(1) >= SV(2) >= ... >= SV(N) >= 0.
-C
-C     The columns of Q are the left singular vectors of A, the diagonal
-C     elements of S are the singular values of A and the columns of P
-C     are the right singular vectors of A.
-C
-C     Either or both of Q and P' may be requested.
-C     When P' is computed, it is returned in A.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBQ    CHARACTER*1
-C             Specifies whether the user wishes to compute the matrix Q
-C             of left singular vectors as follows:
-C             = 'V':  Left singular vectors are computed;
-C             = 'N':  No left singular vectors are computed.
-C
-C     JOBP    CHARACTER*1
-C             Specifies whether the user wishes to compute the matrix P'
-C             of right singular vectors as follows:
-C             = 'V':  Right singular vectors are computed;
-C             = 'N':  No right singular vectors are computed.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix A.  N >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N upper triangular part of this
-C             array must contain the upper triangular matrix A.
-C             On exit, if JOBP = 'V', the leading N-by-N part of this
-C             array contains the N-by-N orthogonal matrix  P'; otherwise
-C             the N-by-N upper triangular part of A is used as internal
-C             workspace. The strictly lower triangular part of A is set
-C             internally to zero before the reduction to bidiagonal form
-C             is performed.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     Q       (output) DOUBLE PRECISION array, dimension (LDQ,N)
-C             If JOBQ = 'V', the leading N-by-N part of this array
-C             contains the orthogonal matrix Q.
-C             If JOBQ = 'N', Q is not referenced.
-C
-C     LDQ     INTEGER
-C             The leading dimension of array Q.
-C             LDQ >= 1,  and when JOBQ = 'V',  LDQ >= MAX(1,N).
-C
-C     SV      (output) DOUBLE PRECISION array, dimension (N)
-C             The N singular values of the matrix A, sorted in
-C             descending order.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal LDWORK;
-C             if INFO > 0, DWORK(2:N) contains the unconverged
-C             superdiagonal elements of an upper bidiagonal matrix B
-C             whose diagonal is in SV (not necessarily sorted).
-C             B satisfies A = Q*B*P', so it has the same singular
-C             values as A, and singular vectors related by Q and P'.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1,5*N).
-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             > 0:  the QR algorithm has failed to converge. In this
-C                   case INFO specifies how many superdiagonals did not
-C                   converge (see the description of DWORK).
-C                   This failure is not likely to occur.
-C
-C     METHOD
-C
-C     The routine reduces A to bidiagonal form by means of elementary
-C     reflectors and then uses the QR algorithm on the bidiagonal form.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute of Informatics, Bucharest, and
-C     A. Varga, German Aerospace Center, DLR Oberpfaffenhofen,
-C     March 1998. Based on the RASP routine DTRSVD.
-C
-C     REVISIONS
-C
-C     V. Sima, Feb. 2000.
-C
-C     KEYWORDS
-C
-C     Bidiagonalization, orthogonal transformation, singular value
-C     decomposition, singular values, triangular form.
-C
-C    ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         JOBP, JOBQ
-      INTEGER           INFO, LDA, LDQ, LDWORK, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), DWORK(*), Q(LDQ,*), SV(*)
-C     .. Local Scalars ..
-      LOGICAL           WANTQ, WANTP
-      INTEGER           I, IE, ISCL, ITAUP, ITAUQ, JWORK, MAXWRK,
-     $                  MINWRK, NCOLP, NCOLQ
-      DOUBLE PRECISION  ANRM, BIGNUM, EPS, SMLNUM
-C     .. Local Arrays ..
-      DOUBLE PRECISION  DUM(1)
-C     .. External Functions ..
-      LOGICAL           LSAME
-      INTEGER           ILAENV
-      DOUBLE PRECISION  DLAMCH, DLANTR
-      EXTERNAL          DLAMCH, DLANTR, ILAENV, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DBDSQR, DGEBRD, DLACPY, DLASCL, DLASET, DORGBR,
-     $                  XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX, SQRT
-C     .. Executable Statements ..
-C
-C     Check the input scalar arguments.
-C
-      INFO = 0
-      WANTQ = LSAME( JOBQ, 'V' )
-      WANTP = LSAME( JOBP, 'V' )
-      MINWRK = 1
-      IF( .NOT.WANTQ .AND. .NOT.LSAME( JOBQ, 'N' ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.WANTP .AND. .NOT.LSAME( JOBP, 'N' ) ) THEN
-         INFO = -2
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -5
-      ELSE IF( ( WANTQ .AND. LDQ.LT.MAX( 1, N ) ) .OR.
-     $    ( .NOT.WANTQ .AND. LDQ.LT.1 ) ) THEN
-         INFO = -7
-      END IF
-C
-C     Compute workspace
-C     (Note: Comments in the code beginning "Workspace:" describe the
-C     minimal amount of workspace needed at that point in the code,
-C     as well as the preferred amount for good performance.
-C     NB refers to the optimal block size for the immediately following
-C     subroutine, as returned by ILAENV.)
-C
-      IF( INFO.EQ.0 .AND. LDWORK.GE.1 .AND. N.GT.0 ) THEN
-         MAXWRK = 3*N+2*N*ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 )
-         IF( WANTQ )
-     $      MAXWRK = MAX( MAXWRK, 3*N+N*
-     $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
-         IF( WANTP )
-     $      MAXWRK = MAX( MAXWRK, 3*N+N*
-     $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
-         MINWRK = 5*N
-         MAXWRK = MAX( MAXWRK, MINWRK )
-         DWORK(1) = MAXWRK
-      END IF
-C
-      IF( LDWORK.LT.MINWRK ) THEN
-         INFO = -10
-      END IF
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'MB03UD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( N.EQ.0 ) THEN
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Get machine constants.
-C
-      EPS = DLAMCH( 'P' )
-      SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
-      BIGNUM = ONE / SMLNUM
-C
-C     Scale A if max entry outside range [SMLNUM,BIGNUM].
-C
-      ANRM = DLANTR( 'Max', 'Upper', 'Non-unit', N, N, A, LDA, DUM )
-      ISCL = 0
-      IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
-         ISCL = 1
-         CALL DLASCL( 'Upper', 0, 0, ANRM, SMLNUM, N, N, A, LDA, INFO )
-      ELSE IF( ANRM.GT.BIGNUM ) THEN
-         ISCL = 1
-         CALL DLASCL( 'Upper', 0, 0, ANRM, BIGNUM, N, N, A, LDA, INFO )
-      END IF
-C
-C     Zero out below.
-C
-      IF ( N.GT.1 )
-     $   CALL DLASET( 'Lower', N-1, N-1, ZERO, ZERO, A(2,1), LDA )
-C
-C     Find the singular values and optionally the singular vectors
-C     of the upper triangular matrix A.
-C
-      IE = 1
-      ITAUQ = IE + N
-      ITAUP = ITAUQ + N
-      JWORK = ITAUP + N
-C
-C     First reduce the matrix to bidiagonal form. The diagonal
-C     elements will be in SV and the superdiagonals in DWORK(IE).
-C     (Workspace: need 4*N, prefer 3*N+2*N*NB)
-C
-      CALL DGEBRD( N, N, A, LDA, SV, DWORK(IE), DWORK(ITAUQ),
-     $             DWORK(ITAUP), DWORK(JWORK), LDWORK-JWORK+1, INFO )
-      IF( WANTQ ) THEN
-C
-C        Generate the transformation matrix Q corresponding to the
-C        left singular vectors.
-C        (Workspace: need 4*N, prefer 3*N+N*NB)
-C
-         NCOLQ = N
-         CALL DLACPY( 'Lower', N, N, A, LDA, Q, LDQ )
-         CALL DORGBR( 'Q', N, N, N, Q, LDQ, DWORK(ITAUQ), DWORK(JWORK),
-     $                LDWORK-JWORK+1, INFO )
-      ELSE
-         NCOLQ = 0
-      END IF
-      IF( WANTP ) THEN
-C
-C        Generate the transformation matrix P' corresponding to the
-C        right singular vectors.
-C        (Workspace: need 4*N, prefer 3*N+N*NB)
-C
-         NCOLP = N
-         CALL DORGBR( 'P', N, N, N, A, LDA, DWORK(ITAUP), DWORK(JWORK),
-     $                LDWORK-JWORK+1, INFO )
-      ELSE
-         NCOLP = 0
-      END IF
-      JWORK = IE + N
-C
-C     Perform bidiagonal QR iteration, to obtain all or part of the
-C     singular value decomposition of A.
-C     (Workspace: need 5*N)
-C
-      CALL DBDSQR( 'U', N, NCOLP, NCOLQ, 0, SV, DWORK(IE), A, LDA,
-     $             Q, LDQ, DUM, 1, DWORK(JWORK), INFO )
-C
-C     If DBDSQR failed to converge, copy unconverged superdiagonals
-C     to DWORK(2:N).
-C
-      IF( INFO.NE.0 ) THEN
-         DO 10 I = N - 1, 1, -1
-            DWORK(I+1) = DWORK(I+IE-1)
-   10    CONTINUE
-      END IF
-C
-C     Undo scaling if necessary.
-C
-      IF( ISCL.EQ.1 ) THEN
-         IF( ANRM.GT.BIGNUM )
-     $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, N, 1, SV, N, INFO )
-         IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
-     $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, N-1, 1, DWORK(2), N,
-     $                   INFO )
-         IF( ANRM.LT.SMLNUM )
-     $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, N, 1, SV, N, INFO )
-         IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
-     $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, N-1, 1, DWORK(2), N,
-     $                   INFO )
-      END IF
-C
-C     Return optimal workspace in DWORK(1).
-C
-      DWORK(1) = MAXWRK
-C
-      RETURN
-C *** Last line of MB03UD ***
-      END
--- a/extra/control-devel/src/MB04ID.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,278 +0,0 @@
-      SUBROUTINE MB04ID( N, M, P, L, A, LDA, B, LDB, TAU, 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 compute a QR factorization of an n-by-m matrix A (A = Q * R),
-C     having a p-by-min(p,m) zero triangle in the lower left-hand side
-C     corner, as shown below, for n = 8, m = 7, and p = 2:
-C
-C            [ x x x x x x x ]
-C            [ x x x x x x x ]
-C            [ x x x x x x x ]
-C            [ x x x x x x x ]
-C        A = [ x x x x x x x ],
-C            [ x x x x x x x ]
-C            [ 0 x x x x x x ]
-C            [ 0 0 x x x x x ]
-C
-C     and optionally apply the transformations to an n-by-l matrix B
-C     (from the left). The problem structure is exploited. This
-C     computation is useful, for instance, in combined measurement and
-C     time update of one iteration of the time-invariant Kalman filter
-C     (square root information filter).
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The number of rows of the matrix A.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of columns of the matrix A.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The order of the zero triagle.  P >= 0.
-C
-C     L       (input) INTEGER
-C             The number of columns of the matrix B.  L >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the matrix A. The elements corresponding to the
-C             zero P-by-MIN(P,M) lower trapezoidal/triangular part
-C             (if P > 0) are not referenced.
-C             On exit, the elements on and above the diagonal of this
-C             array contain the MIN(N,M)-by-M upper trapezoidal matrix
-C             R (R is upper triangular, if N >= M) of the QR
-C             factorization, and the relevant elements below the
-C             diagonal contain the trailing components (the vectors v,
-C             see Method) of the elementary reflectors used in the
-C             factorization.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,L)
-C             On entry, the leading N-by-L part of this array must
-C             contain the matrix B.
-C             On exit, the leading N-by-L part of this array contains
-C             the updated matrix B.
-C             If L = 0, this array is not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.
-C             LDB >= MAX(1,N) if L > 0;
-C             LDB >= 1        if L = 0.
-C
-C     TAU     (output) DOUBLE PRECISION array, dimension MIN(N,M)
-C             The scalar factors of the elementary reflectors used.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  The length of the array DWORK.
-C             LDWORK >= MAX(1,M-1,M-P,L).
-C             For optimum performance LDWORK should be larger.
-C
-C             If LDWORK = -1, then a workspace query is assumed;
-C             the routine only calculates the optimal size of the
-C             DWORK array, returns this value as the first entry of
-C             the DWORK array, and no error message related to LDWORK
-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     METHOD
-C
-C     The routine uses min(N,M) Householder transformations exploiting
-C     the zero pattern of the matrix.  A Householder matrix has the form
-C
-C                                     ( 1 ),
-C        H  = I - tau *u *u',    u  = ( v )
-C         i          i  i  i      i   (  i)
-C
-C     where v  is an (N-P+I-2)-vector.  The components of v  are stored
-C            i                                             i
-C     in the i-th column of A, beginning from the location i+1, and
-C     tau  is stored in TAU(i).
-C        i
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is backward stable.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1997.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Jan. 2009,
-C     Apr. 2009.
-C
-C     KEYWORDS
-C
-C     Elementary reflector, QR factorization, orthogonal transformation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER           INFO, L, LDA, LDB, LDWORK, M, N, P
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), DWORK(*), TAU(*)
-C     .. Local Scalars ..
-      LOGICAL           LQUERY
-      INTEGER           I, NB, WRKOPT
-      DOUBLE PRECISION  FIRST
-C     .. External Functions ..
-      INTEGER           ILAENV
-      EXTERNAL          ILAENV
-C     .. External Subroutines ..
-      EXTERNAL          DGEQRF, DLARF, DLARFG, DORMQR, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         INT, MAX, MIN
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      INFO = 0
-      LQUERY = ( LDWORK.EQ.-1 )
-      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( L.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDB.LT.1 .OR. ( L.GT.0 .AND. LDB.LT.N ) ) THEN
-         INFO = -8
-      ELSE
-         I = MAX( 1, M - 1, M - P, L )
-         IF( LQUERY ) THEN
-            IF( M.GT.P ) THEN
-               NB = ILAENV( 1, 'DGEQRF', ' ', N-P, M-P, -1, -1 )
-               WRKOPT = MAX( I, ( M - P )*NB )
-               IF ( L.GT.0 ) THEN
-                  NB = MIN( 64, ILAENV( 1, 'DORMQR', 'LT', N-P, L,
-     $                                  MIN(N,M)-P, -1 ) )
-                  WRKOPT = MAX( WRKOPT, MAX( 1, L )*NB )
-               END IF
-            END IF
-         ELSE IF( LDWORK.LT.I ) THEN
-            INFO = -11
-         END IF
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'MB04ID', -INFO )
-         RETURN
-      ELSE IF( LQUERY ) THEN
-         DWORK(1) = WRKOPT
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( M, N ).EQ.0 ) THEN
-         DWORK(1) = ONE
-         RETURN
-      ELSE IF( N.LE.P+1 ) THEN
-         DO 5 I = 1, MIN( N, M )
-            TAU(I) = ZERO
-    5    CONTINUE
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Annihilate the subdiagonal elements of A and apply the
-C     transformations to B, if L > 0.
-C     Workspace: need MAX(M-1,L).
-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
-      DO 10 I = 1, MIN( P, M )
-C
-C        Exploit the structure of the I-th column of A.
-C
-         CALL DLARFG( N-P, A(I,I), A(I+1,I), 1, TAU(I) )
-         IF( TAU(I).NE.ZERO ) THEN
-C
-            FIRST = A(I,I)
-            A(I,I) = ONE
-C
-            IF ( I.LT.M ) CALL DLARF( 'Left', N-P, M-I, A(I,I), 1,
-     $                                TAU(I), A(I,I+1), LDA, DWORK )
-            IF ( L.GT.0 ) CALL DLARF( 'Left', N-P, L, A(I,I), 1, TAU(I),
-     $                                B(I,1), LDB, DWORK )
-C
-            A(I,I) = FIRST
-         END IF
-   10 CONTINUE
-C
-      WRKOPT = MAX( 1, M - 1, L )
-C
-C     Fast QR factorization of the remaining right submatrix, if any.
-C     Workspace: need M-P;  prefer (M-P)*NB.
-C
-      IF( M.GT.P ) THEN
-         CALL DGEQRF( N-P, M-P, A(P+1,P+1), LDA, TAU(P+1), DWORK,
-     $                LDWORK, INFO )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) )
-C
-         IF ( L.GT.0 ) THEN
-C
-C           Apply the transformations to B.
-C           Workspace: need L;  prefer L*NB.
-C
-            CALL DORMQR( 'Left', 'Transpose', N-P, L, MIN(N,M)-P,
-     $                   A(P+1,P+1), LDA, TAU(P+1), B(P+1,1), LDB,
-     $                   DWORK, LDWORK, INFO )
-            WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) )
-         END IF
-      END IF
-C
-      DWORK(1) = WRKOPT
-      RETURN
-C *** Last line of MB04ID ***
-      END
--- a/extra/control-devel/src/MB04IY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,327 +0,0 @@
-      SUBROUTINE MB04IY( SIDE, TRANS, N, M, K, P, A, LDA, TAU, C, LDC,
-     $                   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 overwrite the real n-by-m matrix  C  with  Q' * C,  Q * C,
-C     C * Q',  or  C * Q,  according to the following table
-C
-C                     SIDE = 'L'     SIDE = 'R'
-C     TRANS = 'N':      Q * C          C * Q
-C     TRANS = 'T':      Q'* C          C * Q'
-C
-C     where  Q  is a real orthogonal matrix defined as the product of
-C     k elementary reflectors
-C
-C        Q = H(1) H(2) . . . H(k)
-C
-C     as returned by SLICOT Library routine MB04ID.  Q  is of order n
-C     if  SIDE = 'L'  and of order m if  SIDE = 'R'.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     SIDE    CHARACTER*1
-C             Specify if  Q  or  Q'  is applied from the left or right,
-C             as follows:
-C             = 'L':  apply  Q  or  Q'  from the left;
-C             = 'R':  apply  Q  or  Q'  from the right.
-C
-C     TRANS   CHARACTER*1
-C             Specify if  Q  or  Q'  is to be applied, as follows:
-C             = 'N':  apply  Q   (No transpose);
-C             = 'T':  apply  Q'  (Transpose).
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The number of rows of the matrix C.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of columns of the matrix C.  M >= 0.
-C
-C     K       (input) INTEGER
-C             The number of elementary reflectors whose product defines
-C             the matrix Q.
-C             N >= K >= 0,  if  SIDE = 'L';
-C             M >= K >= 0,  if  SIDE = 'R'.
-C
-C     P       (input) INTEGER
-C             The order of the zero triagle (or the number of rows of
-C             the zero trapezoid) in the matrix triangularized by SLICOT
-C             Library routine MB04ID.  P >= 0.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,K)
-C             On input, the elements in the rows  i+1:min(n,n-p-1+i)  of
-C             the  i-th  column, and  TAU(i),  represent the orthogonal
-C             reflector  H(i),  so that matrix  Q  is the product of
-C             elementary reflectors:  Q = H(1) H(2) . . . H(k).
-C             A is modified by the routine but restored on exit.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array  A.
-C             LDA >= max(1,N),  if  SIDE = 'L';
-C             LDA >= max(1,M),  if  SIDE = 'R'.
-C
-C     TAU     (input) DOUBLE PRECISION array, dimension (K)
-C             The scalar factors of the elementary reflectors.
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the matrix  C.
-C             On exit, the leading N-by-M part of this array contains
-C             the updated matrix C.
-C
-C     LDC     INTEGER
-C             The leading dimension of the array  C.  LDC >= max(1,N).
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1,M),  if  SIDE = 'L';
-C             LDWORK >= MAX(1,N),  if  SIDE = 'R'.
-C             For optimum performance LDWORK >= M*NB if SIDE = 'L',
-C             or LDWORK >= N*NB if SIDE = 'R', where NB is the optimal
-C             block size.
-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     METHOD
-C
-C     If  SIDE = 'L',  each elementary reflector  H(i)  modifies
-C     n-p  elements of each column of  C,  for  i = 1:p+1,  and
-C     n-i+1  elements, for  i = p+2:k.
-C     If  SIDE = 'R',  each elementary reflector  H(i)  modifies
-C     m-p  elements of each row of  C,  for  i = 1:p+1,  and
-C     m-i+1  elements, for  i = p+2:k.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented method is numerically stable.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 1999.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Matrix operations, QR decomposition.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ONE
-      PARAMETER          ( ONE = 1.0D+0 )
-C     .. Scalar Arguments ..
-      INTEGER            INFO, K, LDA, LDC, LDWORK, M, N, P
-      CHARACTER          SIDE, TRANS
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), DWORK( * ), TAU( * )
-C     .. Local Scalars ..
-      LOGICAL            LEFT, TRAN
-      INTEGER            I
-      DOUBLE PRECISION   AII, WRKOPT
-C     .. External Functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     .. External Subroutines ..
-      EXTERNAL           DLARF, DORMQR, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          DBLE, MAX, MIN
-C     .. Executable Statements ..
-C
-C     Check the scalar input arguments.
-C
-      INFO = 0
-      LEFT = LSAME( SIDE,  'L' )
-      TRAN = LSAME( TRANS, 'T' )
-C
-      IF( .NOT.LEFT .AND. .NOT.LSAME( SIDE, 'R' ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.TRAN .AND. .NOT.LSAME( TRANS, 'N' ) ) THEN
-         INFO = -2
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( K.LT.0 .OR. ( LEFT .AND. K.GT.N ) .OR.
-     $                ( .NOT.LEFT .AND. K.GT.M ) ) THEN
-         INFO = -5
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( ( LEFT .AND. LDA.LT.MAX( 1, N ) ) .OR.
-     $    ( .NOT.LEFT .AND. LDA.LT.MAX( 1, M ) ) ) THEN
-         INFO = -8
-      ELSE IF( LDC.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( ( LEFT .AND. LDWORK.LT.MAX( 1, M ) ) .OR.
-     $    ( .NOT.LEFT .AND. LDWORK.LT.MAX( 1, N ) ) ) THEN
-         INFO = -13
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'MB04IY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( M.EQ.0 .OR. N.EQ.0 .OR. K.EQ.0 .OR. ( LEFT .AND. N.LT.P )
-     $           .OR. ( .NOT.LEFT .AND. M.LT.P ) ) THEN
-         DWORK(1) = ONE
-         RETURN
-      END IF
-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( LEFT ) THEN
-         WRKOPT = DBLE( M )
-         IF( TRAN ) THEN
-C
-            DO 10 I = 1, MIN( K, P )
-C
-C              Apply H(i) to C(i:i+n-p-1,1:m), from the left.
-C              Workspace: need M.
-C
-               AII = A( I, I )
-               A( I, I ) = ONE
-               CALL DLARF( SIDE, N-P, M, A( I, I ), 1, TAU( I ),
-     $                     C( I, 1 ), LDC, DWORK )
-               A( I, I ) = AII
-   10       CONTINUE
-C
-            IF ( P.LE.MIN( N, K ) ) THEN
-C
-C              Apply H(i) to C, i = p+1:k, from the left.
-C              Workspace: need M;  prefer M*NB.
-C
-               CALL DORMQR( SIDE, TRANS, N-P, M, K-P, A( P+1, P+1 ),
-     $                      LDA, TAU( P+1 ), C( P+1, 1 ), LDC, DWORK,
-     $                      LDWORK, I )
-               WRKOPT = MAX( WRKOPT, DWORK( 1 ) )
-            END IF
-C
-         ELSE
-C
-            IF ( P.LE.MIN( N, K ) ) THEN
-C
-C              Apply H(i) to C, i = k:p+1:-1, from the left.
-C              Workspace: need M;  prefer M*NB.
-C
-               CALL DORMQR( SIDE, TRANS, N-P, M, K-P, A( P+1, P+1 ),
-     $                      LDA, TAU( P+1 ), C( P+1, 1 ), LDC, DWORK,
-     $                      LDWORK, I )
-               WRKOPT = MAX( WRKOPT, DWORK( 1 ) )
-            END IF
-C
-            DO 20 I = MIN( K, P ), 1, -1
-C
-C              Apply H(i) to C(i:i+n-p-1,1:m), from the left.
-C              Workspace: need M.
-C
-               AII = A( I, I )
-               A( I, I ) = ONE
-               CALL DLARF( SIDE, N-P, M, A( I, I ), 1, TAU( I ),
-     $                     C( I, 1 ), LDC, DWORK )
-               A( I, I ) = AII
-   20       CONTINUE
-         END IF
-C
-      ELSE
-C
-         WRKOPT = DBLE( N )
-         IF( TRAN ) THEN
-C
-            IF ( P.LE.MIN( M, K ) ) THEN
-C
-C              Apply H(i) to C, i = k:p+1:-1, from the right.
-C              Workspace: need N;  prefer N*NB.
-C
-               CALL DORMQR( SIDE, TRANS, N, M-P, K-P, A( P+1, P+1 ),
-     $                      LDA, TAU( P+1 ), C( 1, P+1 ), LDC, DWORK,
-     $                      LDWORK, I )
-               WRKOPT = MAX( WRKOPT, DWORK( 1 ) )
-            END IF
-C
-            DO 30 I = MIN( K, P ), 1, -1
-C
-C              Apply H(i) to C(1:n,i:i+m-p-1), from the right.
-C              Workspace: need N.
-C
-               AII = A( I, I )
-               A( I, I ) = ONE
-               CALL DLARF( SIDE, N, M-P, A( I, I ), 1, TAU( I ),
-     $                     C( 1, I ), LDC, DWORK )
-               A( I, I ) = AII
-   30       CONTINUE
-C
-         ELSE
-C
-            DO 40 I = 1, MIN( K, P )
-C
-C              Apply H(i) to C(1:n,i:i+m-p-1), from the right.
-C              Workspace: need N.
-C
-               AII = A( I, I )
-               A( I, I ) = ONE
-               CALL DLARF( SIDE, N, M-P, A( I, I ), 1, TAU( I ),
-     $                     C( 1, I ), LDC, DWORK )
-               A( I, I ) = AII
-   40       CONTINUE
-C
-            IF ( P.LE.MIN( M, K ) ) THEN
-C
-C              Apply H(i) to C, i = p+1:k, from the right.
-C              Workspace: need N;  prefer N*NB.
-C
-               CALL DORMQR( SIDE, TRANS, N, M-P, K-P, A( P+1, P+1 ),
-     $                      LDA, TAU( P+1 ), C( 1, P+1 ), LDC, DWORK,
-     $                      LDWORK, I )
-               WRKOPT = MAX( WRKOPT, DWORK( 1 ) )
-            END IF
-C
-         END IF
-      END IF
-C
-      DWORK( 1 ) = WRKOPT
-      RETURN
-C
-C *** Last line of MB04IY ***
-      END
--- a/extra/control-devel/src/MB04KD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,209 +0,0 @@
-      SUBROUTINE MB04KD( UPLO, N, M, P, R, LDR, A, LDA, B, LDB, C, LDC,
-     $                   TAU, DWORK )
-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 calculate a QR factorization of the first block column and
-C     apply the orthogonal transformations (from the left) also to the
-C     second block column of a structured matrix, as follows
-C                          _
-C            [ R   0 ]   [ R   C ]
-C       Q' * [       ] = [       ]
-C            [ A   B ]   [ 0   D ]
-C                 _
-C     where R and R are upper triangular. The matrix A can be full or
-C     upper trapezoidal/triangular. The problem structure is exploited.
-C     This computation is useful, for instance, in combined measurement
-C     and time update of one iteration of the Kalman filter (square
-C     root information filter).
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     UPLO    CHARACTER*1
-C             Indicates if the matrix A is or not triangular as follows:
-C             = 'U':  Matrix A is upper trapezoidal/triangular;
-C             = 'F':  Matrix A is full.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER                 _
-C             The order of the matrices R and R.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of columns of the matrices B, C and D.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The number of rows of the matrices A, B and D.  P >= 0.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,N)
-C             On entry, the leading N-by-N upper triangular part of this
-C             array must contain the upper triangular matrix R.
-C             On exit, the leading N-by-N upper triangular part of this
-C                                                        _
-C             array contains the upper triangular matrix R.
-C             The strict lower triangular part of this array is not
-C             referenced.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,N).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, if UPLO = 'F', the leading P-by-N part of this
-C             array must contain the matrix A. If UPLO = 'U', the
-C             leading MIN(P,N)-by-N part of this array must contain the
-C             upper trapezoidal (upper triangular if P >= N) matrix A,
-C             and the elements below the diagonal are not referenced.
-C             On exit, the leading P-by-N part (upper trapezoidal or
-C             triangular, if UPLO = 'U') of this array contains the
-C             trailing components (the vectors v, see Method) of the
-C             elementary reflectors used in the factorization.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,P).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the matrix B.
-C             On exit, the leading P-by-M part of this array contains
-C             the computed matrix D.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,P).
-C
-C     C       (output) DOUBLE PRECISION array, dimension (LDC,M)
-C             The leading N-by-M part of this array contains the
-C             computed matrix C.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,N).
-C
-C     TAU     (output) DOUBLE PRECISION array, dimension (N)
-C             The scalar factors of the elementary reflectors used.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (N)
-C
-C     METHOD
-C
-C     The routine uses N Householder transformations exploiting the zero
-C     pattern of the block matrix.  A Householder matrix has the form
-C
-C                                     ( 1 ),
-C        H  = I - tau *u *u',    u  = ( v )
-C         i          i  i  i      i   (  i)
-C
-C     where v  is a P-vector, if UPLO = 'F', or an min(i,P)-vector, if
-C            i
-C     UPLO = 'U'.  The components of v  are stored in the i-th column
-C                                     i
-C     of A, and tau  is stored in TAU(i).
-C                  i
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is backward stable.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1997.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Elementary reflector, QR factorization, orthogonal transformation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         UPLO
-      INTEGER           LDA, LDB, LDC, LDR, M, N, P
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*),
-     $                  R(LDR,*), TAU(*)
-C     .. Local Scalars ..
-      LOGICAL           LUPLO
-      INTEGER           I, IM
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DCOPY, DGEMV, DGER, DLARFG, DSCAL
-C     .. Intrinsic Functions ..
-      INTRINSIC         MIN
-C     .. Executable Statements ..
-C
-      IF( MIN( N, P ).EQ.0 )
-     $   RETURN
-C
-      LUPLO = LSAME( UPLO, 'U' )
-      IM = P
-C
-      DO 10 I = 1, N
-C
-C        Annihilate the I-th column of A and apply the transformations
-C        to the entire block matrix, exploiting its structure.
-C
-         IF( LUPLO ) IM = MIN( I, P )
-         CALL DLARFG( IM+1, R(I,I), A(1,I), 1, TAU(I) )
-         IF( TAU(I).NE.ZERO ) THEN
-C
-C                                      [ R(I,I+1:N)        0     ]
-C           [ w C(I,:) ] := [ 1 v' ] * [                         ]
-C                                      [ A(1:IM,I+1:N) B(1:IM,:) ]
-C
-            IF( I.LT.N ) THEN
-               CALL DCOPY( N-I, R(I,I+1), LDR, DWORK, 1 )
-               CALL DGEMV( 'Transpose', IM, N-I, ONE, A(1,I+1), LDA,
-     $                     A(1,I), 1, ONE, DWORK, 1 )
-            END IF
-            CALL DGEMV( 'Transpose', IM, M, ONE, B, LDB, A(1,I), 1,
-     $                  ZERO, C(I,1), LDC )
-C
-C           [ R(I,I+1:N)      C(I,:)  ]    [ R(I,I+1:N)        0     ]
-C           [                         ] := [                         ]
-C           [ A(1:IM,I+1:N) D(1:IM,:) ]    [ A(1:IM,I+1:N) B(1:IM,:) ]
-C
-C                                                 [ 1 ]
-C                                         - tau * [   ] * [ w C(I,:) ]
-C                                                 [ v ]
-C
-            IF( I.LT.N ) THEN
-               CALL DAXPY( N-I, -TAU(I), DWORK, 1, R(I,I+1), LDR )
-               CALL DGER( IM, N-I, -TAU(I), A(1,I), 1, DWORK, 1,
-     $                    A(1,I+1), LDA )
-            END IF
-            CALL DSCAL( M, -TAU(I), C(I,1), LDC )
-            CALL DGER( IM, M, ONE, A(1,I), 1, C(I,1), LDC, B, LDB )
-         END IF
-   10 CONTINUE
-C
-      RETURN
-C *** Last line of MB04KD ***
-      END
--- a/extra/control-devel/src/MB04ND.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-      SUBROUTINE MB04ND( UPLO, N, M, P, R, LDR, A, LDA, B, LDB, C, LDC,
-     $                   TAU, DWORK )
-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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To calculate an RQ factorization of the first block row and
-C     apply the orthogonal transformations (from the right) also to the
-C     second block row of a structured matrix, as follows
-C                              _
-C       [ A   R ]        [ 0   R ]
-C       [       ] * Q' = [ _   _ ]
-C       [ C   B ]        [ C   B ]
-C                 _
-C     where R and R are upper triangular. The matrix A can be full or
-C     upper trapezoidal/triangular. The problem structure is exploited.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     UPLO    CHARACTER*1
-C             Indicates if the matrix A is or not triangular as follows:
-C             = 'U':  Matrix A is upper trapezoidal/triangular;
-C             = 'F':  Matrix A is full.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER                 _
-C             The order of the matrices R and R.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrices B and C.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The number of columns of the matrices A and C.  P >= 0.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,N)
-C             On entry, the leading N-by-N upper triangular part of this
-C             array must contain the upper triangular matrix R.
-C             On exit, the leading N-by-N upper triangular part of this
-C                                                        _
-C             array contains the upper triangular matrix R.
-C             The strict lower triangular part of this array is not
-C             referenced.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,N).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,P)
-C             On entry, if UPLO = 'F', the leading N-by-P part of this
-C             array must contain the matrix A. For UPLO = 'U', if
-C             N <= P, the upper triangle of the subarray A(1:N,P-N+1:P)
-C             must contain the N-by-N upper triangular matrix A, and if
-C             N >= P, the elements on and above the (N-P)-th subdiagonal
-C             must contain the N-by-P upper trapezoidal matrix A.
-C             On exit, if UPLO = 'F', the leading N-by-P part of this
-C             array contains the trailing components (the vectors v, see
-C             METHOD) of the elementary reflectors used in the
-C             factorization. If UPLO = 'U', the upper triangle of the
-C             subarray A(1:N,P-N+1:P) (if N <= P), or the elements on
-C             and above the (N-P)-th subdiagonal (if N >= P), contain
-C             the trailing components (the vectors v, see METHOD) of the
-C             elementary reflectors used in the factorization.
-C             The remaining elements are not referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,N)
-C             On entry, the leading M-by-N part of this array must
-C             contain the matrix B.
-C             On exit, the leading M-by-N part of this array contains
-C                                 _
-C             the computed matrix B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,M).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,P)
-C             On entry, the leading M-by-P part of this array must
-C             contain the matrix C.
-C             On exit, the leading M-by-P part of this array contains
-C                                 _
-C             the computed matrix C.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,M).
-C
-C     TAU     (output) DOUBLE PRECISION array, dimension (N)
-C             The scalar factors of the elementary reflectors used.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (MAX(N-1,M))
-C
-C     METHOD
-C
-C     The routine uses N Householder transformations exploiting the zero
-C     pattern of the block matrix.  A Householder matrix has the form
-C
-C                                     ( 1 )
-C        H  = I - tau *u *u',    u  = ( v ),
-C         i          i  i  i      i   (  i)
-C
-C     where v  is a P-vector, if UPLO = 'F', or a min(N-i+1,P)-vector,
-C            i
-C     if UPLO = 'U'.  The components of v  are stored in the i-th row
-C                                        i
-C     of A, and tau  is stored in TAU(i), i = N,N-1,...,1.
-C                  i
-C     In-line code for applying Householder transformations is used
-C     whenever possible (see MB04NY routine).
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is backward stable.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Apr. 1998.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Elementary reflector, RQ factorization, orthogonal transformation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         UPLO
-      INTEGER           LDA, LDB, LDC, LDR, M, N, P
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*),
-     $                  R(LDR,*), TAU(*)
-C     .. Local Scalars ..
-      LOGICAL           LUPLO
-      INTEGER           I, IM, IP
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DLARFG, MB04NY
-C     .. Intrinsic Functions ..
-      INTRINSIC         MIN
-C     .. Executable Statements ..
-C
-C     For efficiency reasons, the parameters are not checked.
-C
-      IF( MIN( N, P ).EQ.0 )
-     $   RETURN
-C
-      LUPLO = LSAME( UPLO, 'U' )
-      IF ( LUPLO ) THEN
-C
-         DO 10 I = N, 1, -1
-C
-C           Annihilate the I-th row of A and apply the transformations
-C           to the entire block matrix, exploiting its structure.
-C
-            IM = MIN( N-I+1, P )
-            IP = MAX( P-N+I, 1 )
-            CALL DLARFG( IM+1, R(I,I), A(I,IP), LDA, TAU(I) )
-C
-C           Compute
-C                                                [ 1 ]
-C           w := [ R(1:I-1,I)  A(1:I-1,IP:P) ] * [   ],
-C                                                [ v ]
-C
-C           [ R(1:I-1,I)  A(1:I-1,IP:P) ] =
-C           [ R(1:I-1,I)  A(1:I-1,IP:P) ] - tau * w * [ 1 v' ].
-C
-            IF ( I.GT.0 )
-C
-     $         CALL MB04NY( I-1, IM, A(I,IP), LDA, TAU(I), R(1,I), LDR,
-     $                      A(1,IP), LDA, DWORK )
-C
-C           Compute
-C                                        [ 1 ]
-C           w := [ B(:,I)  C(:,IP:P) ] * [   ],
-C                                        [ v ]
-C
-C           [ B(:,I)  C(:,IP:P) ] = [ B(:,I)  C(:,IP:P) ] -
-C                                   tau * w * [ 1 v' ].
-C
-            IF ( M.GT.0 )
-     $         CALL MB04NY( M, IM, A(I,IP), LDA, TAU(I), B(1,I), LDB,
-     $                      C(1,IP), LDC, DWORK )
-   10    CONTINUE
-C
-      ELSE
-C
-         DO 20 I = N, 2 , -1
-C
-C           Annihilate the I-th row of A and apply the transformations
-C           to the first block row, exploiting its structure.
-C
-            CALL DLARFG( P+1, R(I,I), A(I,1), LDA, TAU(I) )
-C
-C           Compute
-C                                             [ 1 ]
-C           w := [ R(1:I-1,I)  A(1:I-1,:) ] * [   ],
-C                                             [ v ]
-C
-C           [ R(1:I-1,I)  A(1:I-1,:) ] = [ R(1:I-1,I)  A(1:I-1,:) ] -
-C                                        tau * w * [ 1 v' ].
-C
-            CALL MB04NY( I-1, P, A(I,1), LDA, TAU(I), R(1,I), LDR, A,
-     $                   LDA, DWORK )
-   20    CONTINUE
-C
-         CALL DLARFG( P+1, R(1,1), A(1,1), LDA, TAU(1) )
-         IF ( M.GT.0 ) THEN
-C
-C           Apply the transformations to the second block row.
-C
-            DO 30 I = N, 1, -1
-C
-C              Compute
-C                                   [ 1 ]
-C              w := [ B(:,I)  C ] * [   ],
-C                                   [ v ]
-C
-C              [ B(:,I)  C ] = [ B(:,I)  C ] - tau * w * [ 1 v' ].
-C
-               CALL MB04NY( M, P, A(I,1), LDA, TAU(I), B(1,I), LDB, C,
-     $                      LDC, DWORK )
-   30       CONTINUE
-C
-         END IF
-      END IF
-      RETURN
-C *** Last line of MB04ND ***
-      END
--- a/extra/control-devel/src/MB04NY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,437 +0,0 @@
-      SUBROUTINE MB04NY( M, N, V, INCV, TAU, A, LDA, B, LDB, DWORK )
-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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To apply a real elementary reflector H to a real m-by-(n+1)
-C     matrix C = [ A  B ], from the right, where A has one column. H is
-C     represented in the form
-C                                        ( 1 )
-C           H = I - tau * u *u',    u  = (   ),
-C                                        ( v )
-C     where tau is a real scalar and v is a real n-vector.
-C
-C     If tau = 0, then H is taken to be the unit matrix.
-C
-C     In-line code is used if H has order < 11.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrices A and B.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrix B.  N >= 0.
-C
-C     V       (input) DOUBLE PRECISION array, dimension
-C             (1+(N-1)*ABS( INCV ))
-C             The vector v in the representation of H.
-C
-C     INCV    (input) INTEGER
-C             The increment between the elements of v.  INCV <> 0.
-C
-C     TAU     (input) DOUBLE PRECISION
-C             The scalar factor of the elementary reflector H.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,1)
-C             On entry, the leading M-by-1 part of this array must
-C             contain the matrix A.
-C             On exit, the leading M-by-1 part of this array contains
-C             the updated matrix A (the first column of C * H).
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,M).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,N)
-C             On entry, the leading M-by-N part of this array must
-C             contain the matrix B.
-C             On exit, the leading M-by-N part of this array contains
-C             the updated matrix B (the last n columns of C * H).
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,M).
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (M)
-C             DWORK is not referenced if H has order less than 11.
-C
-C     METHOD
-C
-C     The routine applies the elementary reflector H, taking the special
-C     structure of C into account.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is backward stable.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Apr. 1998.
-C     Based on LAPACK routines DLARFX and DLATZM.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, elementary reflector, orthogonal
-C     transformation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER           INCV, LDA, LDB, M, N
-      DOUBLE PRECISION  TAU
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A( LDA, * ), B( LDB, * ), DWORK( * ), V( * )
-C     .. Local Scalars ..
-      INTEGER           IV, J
-      DOUBLE PRECISION  SUM, T1, T2, T3, T4, T5, T6, T7, T8, T9, V1, V2,
-     $                  V3, V4, V5, V6, V7, V8, V9
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DCOPY, DGEMV, DGER
-C
-C     .. Executable Statements ..
-C
-      IF( TAU.EQ.ZERO )
-     $   RETURN
-C
-C     Form  C * H, where H has order n+1.
-C
-      GO TO ( 10, 30, 50, 70, 90, 110, 130, 150,
-     $        170, 190 ) N+1
-C
-C     Code for general N. Compute
-C
-C     w := C*u,  C := C - tau * w * u'.
-C
-      CALL DCOPY( M, A, 1, DWORK, 1 )
-      CALL DGEMV( 'No transpose', M, N, ONE, B, LDB, V, INCV, ONE,
-     $            DWORK, 1 )
-      CALL DAXPY( M, -TAU, DWORK, 1, A, 1 )
-      CALL DGER( M, N, -TAU, DWORK, 1, V, INCV, B, LDB )
-      GO TO 210
-   10 CONTINUE
-C
-C     Special code for 1 x 1 Householder
-C
-      T1 = ONE - TAU
-      DO 20 J = 1, M
-         A( J, 1 ) = T1*A( J, 1 )
-   20 CONTINUE
-      GO TO 210
-   30 CONTINUE
-C
-C     Special code for 2 x 2 Householder
-C
-      IV = 1
-      IF( INCV.LT.0 )
-     $   IV = (-N+1)*INCV + 1
-      V1 = V( IV )
-      T1 = TAU*V1
-      DO 40 J = 1, M
-         SUM = A( J, 1 ) + V1*B( J, 1 )
-         A( J, 1 ) = A( J, 1 ) - SUM*TAU
-         B( J, 1 ) = B( J, 1 ) - SUM*T1
-   40 CONTINUE
-      GO TO 210
-   50 CONTINUE
-C
-C     Special code for 3 x 3 Householder
-C
-      IV = 1
-      IF( INCV.LT.0 )
-     $   IV = (-N+1)*INCV + 1
-      V1 = V( IV )
-      T1 = TAU*V1
-      IV = IV + INCV
-      V2 = V( IV )
-      T2 = TAU*V2
-      DO 60 J = 1, M
-         SUM = A( J, 1 ) + V1*B( J, 1 ) + V2*B( J, 2 )
-         A( J, 1 ) = A( J, 1 ) - SUM*TAU
-         B( J, 1 ) = B( J, 1 ) - SUM*T1
-         B( J, 2 ) = B( J, 2 ) - SUM*T2
-   60 CONTINUE
-      GO TO 210
-   70 CONTINUE
-C
-C     Special code for 4 x 4 Householder
-C
-      IV = 1
-      IF( INCV.LT.0 )
-     $   IV = (-N+1)*INCV + 1
-      V1 = V( IV )
-      T1 = TAU*V1
-      IV = IV + INCV
-      V2 = V( IV )
-      T2 = TAU*V2
-      IV = IV + INCV
-      V3 = V( IV )
-      T3 = TAU*V3
-      DO 80 J = 1, M
-         SUM = A( J, 1 ) + V1*B( J, 1 ) + V2*B( J, 2 ) + V3*B( J, 3 )
-         A( J, 1 ) = A( J, 1 ) - SUM*TAU
-         B( J, 1 ) = B( J, 1 ) - SUM*T1
-         B( J, 2 ) = B( J, 2 ) - SUM*T2
-         B( J, 3 ) = B( J, 3 ) - SUM*T3
-   80 CONTINUE
-      GO TO 210
-   90 CONTINUE
-C
-C     Special code for 5 x 5 Householder
-C
-      IV = 1
-      IF( INCV.LT.0 )
-     $   IV = (-N+1)*INCV + 1
-      V1 = V( IV )
-      T1 = TAU*V1
-      IV = IV + INCV
-      V2 = V( IV )
-      T2 = TAU*V2
-      IV = IV + INCV
-      V3 = V( IV )
-      T3 = TAU*V3
-      IV = IV + INCV
-      V4 = V( IV )
-      T4 = TAU*V4
-      DO 100 J = 1, M
-         SUM = A( J, 1 ) +  V1*B( J, 1 ) + V2*B( J, 2 ) + V3*B( J, 3 ) +
-     $                      V4*B( J, 4 )
-         A( J, 1 ) = A( J, 1 ) - SUM*TAU
-         B( J, 1 ) = B( J, 1 ) - SUM*T1
-         B( J, 2 ) = B( J, 2 ) - SUM*T2
-         B( J, 3 ) = B( J, 3 ) - SUM*T3
-         B( J, 4 ) = B( J, 4 ) - SUM*T4
-  100 CONTINUE
-      GO TO 210
-  110 CONTINUE
-C
-C     Special code for 6 x 6 Householder
-C
-      IV = 1
-      IF( INCV.LT.0 )
-     $   IV = (-N+1)*INCV + 1
-      V1 = V( IV )
-      T1 = TAU*V1
-      IV = IV + INCV
-      V2 = V( IV )
-      T2 = TAU*V2
-      IV = IV + INCV
-      V3 = V( IV )
-      T3 = TAU*V3
-      IV = IV + INCV
-      V4 = V( IV )
-      T4 = TAU*V4
-      IV = IV + INCV
-      V5 = V( IV )
-      T5 = TAU*V5
-      DO 120 J = 1, M
-         SUM = A( J, 1 ) +  V1*B( J, 1 ) + V2*B( J, 2 ) + V3*B( J, 3 ) +
-     $                      V4*B( J, 4 ) + V5*B( J, 5 )
-         A( J, 1 ) = A( J, 1 ) - SUM*TAU
-         B( J, 1 ) = B( J, 1 ) - SUM*T1
-         B( J, 2 ) = B( J, 2 ) - SUM*T2
-         B( J, 3 ) = B( J, 3 ) - SUM*T3
-         B( J, 4 ) = B( J, 4 ) - SUM*T4
-         B( J, 5 ) = B( J, 5 ) - SUM*T5
-  120 CONTINUE
-      GO TO 210
-  130 CONTINUE
-C
-C     Special code for 7 x 7 Householder
-C
-      IV = 1
-      IF( INCV.LT.0 )
-     $   IV = (-N+1)*INCV + 1
-      V1 = V( IV )
-      T1 = TAU*V1
-      IV = IV + INCV
-      V2 = V( IV )
-      T2 = TAU*V2
-      IV = IV + INCV
-      V3 = V( IV )
-      T3 = TAU*V3
-      IV = IV + INCV
-      V4 = V( IV )
-      T4 = TAU*V4
-      IV = IV + INCV
-      V5 = V( IV )
-      T5 = TAU*V5
-      IV = IV + INCV
-      V6 = V( IV )
-      T6 = TAU*V6
-      DO 140 J = 1, M
-         SUM = A( J, 1 ) +  V1*B( J, 1 ) + V2*B( J, 2 ) + V3*B( J, 3 ) +
-     $                      V4*B( J, 4 ) + V5*B( J, 5 ) + V6*B( J, 6 )
-         A( J, 1 ) = A( J, 1 ) - SUM*TAU
-         B( J, 1 ) = B( J, 1 ) - SUM*T1
-         B( J, 2 ) = B( J, 2 ) - SUM*T2
-         B( J, 3 ) = B( J, 3 ) - SUM*T3
-         B( J, 4 ) = B( J, 4 ) - SUM*T4
-         B( J, 5 ) = B( J, 5 ) - SUM*T5
-         B( J, 6 ) = B( J, 6 ) - SUM*T6
-  140 CONTINUE
-      GO TO 210
-  150 CONTINUE
-C
-C     Special code for 8 x 8 Householder
-C
-      IV = 1
-      IF( INCV.LT.0 )
-     $   IV = (-N+1)*INCV + 1
-      V1 = V( IV )
-      T1 = TAU*V1
-      IV = IV + INCV
-      V2 = V( IV )
-      T2 = TAU*V2
-      IV = IV + INCV
-      V3 = V( IV )
-      T3 = TAU*V3
-      IV = IV + INCV
-      V4 = V( IV )
-      T4 = TAU*V4
-      IV = IV + INCV
-      V5 = V( IV )
-      T5 = TAU*V5
-      IV = IV + INCV
-      V6 = V( IV )
-      T6 = TAU*V6
-      IV = IV + INCV
-      V7 = V( IV )
-      T7 = TAU*V7
-      DO 160 J = 1, M
-         SUM = A( J, 1 ) +  V1*B( J, 1 ) + V2*B( J, 2 ) + V3*B( J, 3 ) +
-     $                      V4*B( J, 4 ) + V5*B( J, 5 ) + V6*B( J, 6 ) +
-     $                      V7*B( J, 7 )
-         A( J, 1 ) = A( J, 1 ) - SUM*TAU
-         B( J, 1 ) = B( J, 1 ) - SUM*T1
-         B( J, 2 ) = B( J, 2 ) - SUM*T2
-         B( J, 3 ) = B( J, 3 ) - SUM*T3
-         B( J, 4 ) = B( J, 4 ) - SUM*T4
-         B( J, 5 ) = B( J, 5 ) - SUM*T5
-         B( J, 6 ) = B( J, 6 ) - SUM*T6
-         B( J, 7 ) = B( J, 7 ) - SUM*T7
-  160 CONTINUE
-      GO TO 210
-  170 CONTINUE
-C
-C     Special code for 9 x 9 Householder
-C
-      IV = 1
-      IF( INCV.LT.0 )
-     $   IV = (-N+1)*INCV + 1
-      V1 = V( IV )
-      T1 = TAU*V1
-      IV = IV + INCV
-      V2 = V( IV )
-      T2 = TAU*V2
-      IV = IV + INCV
-      V3 = V( IV )
-      T3 = TAU*V3
-      IV = IV + INCV
-      V4 = V( IV )
-      T4 = TAU*V4
-      IV = IV + INCV
-      V5 = V( IV )
-      T5 = TAU*V5
-      IV = IV + INCV
-      V6 = V( IV )
-      T6 = TAU*V6
-      IV = IV + INCV
-      V7 = V( IV )
-      T7 = TAU*V7
-      IV = IV + INCV
-      V8 = V( IV )
-      T8 = TAU*V8
-      DO 180 J = 1, M
-         SUM = A( J, 1 ) +  V1*B( J, 1 ) + V2*B( J, 2 ) + V3*B( J, 3 ) +
-     $                      V4*B( J, 4 ) + V5*B( J, 5 ) + V6*B( J, 6 ) +
-     $                      V7*B( J, 7 ) + V8*B( J, 8 )
-         A( J, 1 ) = A( J, 1 ) - SUM*TAU
-         B( J, 1 ) = B( J, 1 ) - SUM*T1
-         B( J, 2 ) = B( J, 2 ) - SUM*T2
-         B( J, 3 ) = B( J, 3 ) - SUM*T3
-         B( J, 4 ) = B( J, 4 ) - SUM*T4
-         B( J, 5 ) = B( J, 5 ) - SUM*T5
-         B( J, 6 ) = B( J, 6 ) - SUM*T6
-         B( J, 7 ) = B( J, 7 ) - SUM*T7
-         B( J, 8 ) = B( J, 8 ) - SUM*T8
-  180 CONTINUE
-      GO TO 210
-  190 CONTINUE
-C
-C     Special code for 10 x 10 Householder
-C
-      IV = 1
-      IF( INCV.LT.0 )
-     $   IV = (-N+1)*INCV + 1
-      V1 = V( IV )
-      T1 = TAU*V1
-      IV = IV + INCV
-      V2 = V( IV )
-      T2 = TAU*V2
-      IV = IV + INCV
-      V3 = V( IV )
-      T3 = TAU*V3
-      IV = IV + INCV
-      V4 = V( IV )
-      T4 = TAU*V4
-      IV = IV + INCV
-      V5 = V( IV )
-      T5 = TAU*V5
-      IV = IV + INCV
-      V6 = V( IV )
-      T6 = TAU*V6
-      IV = IV + INCV
-      V7 = V( IV )
-      T7 = TAU*V7
-      IV = IV + INCV
-      V8 = V( IV )
-      T8 = TAU*V8
-      IV = IV + INCV
-      V9 = V( IV )
-      T9 = TAU*V9
-      DO 200 J = 1, M
-         SUM = A( J, 1 ) +  V1*B( J, 1 ) + V2*B( J, 2 ) + V3*B( J, 3 ) +
-     $                      V4*B( J, 4 ) + V5*B( J, 5 ) + V6*B( J, 6 ) +
-     $                      V7*B( J, 7 ) + V8*B( J, 8 ) + V9*B( J, 9 )
-         A( J, 1 ) = A( J, 1 ) - SUM*TAU
-         B( J, 1 ) = B( J, 1 ) - SUM*T1
-         B( J, 2 ) = B( J, 2 ) - SUM*T2
-         B( J, 3 ) = B( J, 3 ) - SUM*T3
-         B( J, 4 ) = B( J, 4 ) - SUM*T4
-         B( J, 5 ) = B( J, 5 ) - SUM*T5
-         B( J, 6 ) = B( J, 6 ) - SUM*T6
-         B( J, 7 ) = B( J, 7 ) - SUM*T7
-         B( J, 8 ) = B( J, 8 ) - SUM*T8
-         B( J, 9 ) = B( J, 9 ) - SUM*T9
-  200 CONTINUE
-  210 CONTINUE
-      RETURN
-C *** Last line of MB04NY ***
-      END
--- a/extra/control-devel/src/MB04OD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,257 +0,0 @@
-      SUBROUTINE MB04OD( UPLO, N, M, P, R, LDR, A, LDA, B, LDB, C, LDC,
-     $                   TAU, DWORK )
-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 calculate a QR factorization of the first block column and
-C     apply the orthogonal transformations (from the left) also to the
-C     second block column of a structured matrix, as follows
-C                          _   _
-C            [ R   B ]   [ R   B ]
-C       Q' * [       ] = [     _ ]
-C            [ A   C ]   [ 0   C ]
-C                 _
-C     where R and R are upper triangular. The matrix A can be full or
-C     upper trapezoidal/triangular. The problem structure is exploited.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     UPLO    CHARACTER*1
-C             Indicates if the matrix A is or not triangular as follows:
-C             = 'U':  Matrix A is upper trapezoidal/triangular;
-C             = 'F':  Matrix A is full.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER                 _
-C             The order of the matrices R and R.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of columns of the matrices B and C.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The number of rows of the matrices A and C.  P >= 0.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,N)
-C             On entry, the leading N-by-N upper triangular part of this
-C             array must contain the upper triangular matrix R.
-C             On exit, the leading N-by-N upper triangular part of this
-C                                                        _
-C             array contains the upper triangular matrix R.
-C             The strict lower triangular part of this array is not
-C             referenced.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,N).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, if UPLO = 'F', the leading P-by-N part of this
-C             array must contain the matrix A. If UPLO = 'U', the
-C             leading MIN(P,N)-by-N part of this array must contain the
-C             upper trapezoidal (upper triangular if P >= N) matrix A,
-C             and the elements below the diagonal are not referenced.
-C             On exit, the leading P-by-N part (upper trapezoidal or
-C             triangular, if UPLO = 'U') of this array contains the
-C             trailing components (the vectors v, see Method) of the
-C             elementary reflectors used in the factorization.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,P).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the matrix B.
-C             On exit, the leading N-by-M part of this array contains
-C                                 _
-C             the computed matrix B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the matrix C.
-C             On exit, the leading P-by-M part of this array contains
-C                                 _
-C             the computed matrix C.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     TAU     (output) DOUBLE PRECISION array, dimension (N)
-C             The scalar factors of the elementary reflectors used.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (MAX(N-1,M))
-C
-C     METHOD
-C
-C     The routine uses N Householder transformations exploiting the zero
-C     pattern of the block matrix.  A Householder matrix has the form
-C
-C                                     ( 1 )
-C        H  = I - tau *u *u',    u  = ( v ),
-C         i          i  i  i      i   (  i)
-C
-C     where v  is a P-vector, if UPLO = 'F', or a min(i,P)-vector, if
-C            i
-C     UPLO = 'U'.  The components of v  are stored in the i-th column
-C                                     i
-C     of A, and tau  is stored in TAU(i).
-C                  i
-C     In-line code for applying Householder transformations is used
-C     whenever possible (see MB04OY routine).
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is backward stable.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1997.
-C
-C     REVISIONS
-C
-C     Dec. 1997.
-C
-C     KEYWORDS
-C
-C     Elementary reflector, QR factorization, orthogonal transformation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         UPLO
-      INTEGER           LDA, LDB, LDC, LDR, M, N, P
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*),
-     $                  R(LDR,*), TAU(*)
-C     .. Local Scalars ..
-      LOGICAL           LUPLO
-      INTEGER           I, IM
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DLARFG, MB04OY
-C     .. Intrinsic Functions ..
-      INTRINSIC         MIN
-C     .. Executable Statements ..
-C
-C     For efficiency reasons, the parameters are not checked.
-C
-      IF( MIN( N, P ).EQ.0 )
-     $   RETURN
-C
-      LUPLO = LSAME( UPLO, 'U' )
-      IF ( LUPLO ) THEN
-C
-         DO 10 I = 1, N
-C
-C           Annihilate the I-th column of A and apply the
-C           transformations to the entire block matrix, exploiting
-C           its structure.
-C
-            IM = MIN( I, P )
-            CALL DLARFG( IM+1, R(I,I), A(1,I), 1, TAU(I) )
-C
-C           Compute
-C                           [ R(I,I+1:N)    ]
-C           w := [ 1 v' ] * [               ],
-C                           [ A(1:IM,I+1:N) ]
-C
-C           [ R(I,I+1:N)    ]    [ R(I,I+1:N)    ]         [ 1 ]
-C           [               ] := [               ] - tau * [   ] * w .
-C           [ A(1:IM,I+1:N) ]    [ A(1:IM,I+1:N) ]         [ v ]
-C
-            IF ( N-I.GT.0 )
-     $         CALL MB04OY( IM, N-I, A(1,I), TAU(I), R(I,I+1), LDR,
-     $                      A(1,I+1), LDA, DWORK )
-C
-C           Compute
-C                           [  B(I,:)   ]
-C           w := [ 1 v' ] * [           ],
-C                           [ C(1:IM,:) ]
-C
-C           [   B(I,:)  ]    [  B(I,:)   ]         [ 1 ]
-C           [           ] := [           ] - tau * [   ] * w.
-C           [ C(1:IM,:) ]    [ C(1:IM,:) ]         [ v ]
-C
-C
-            IF ( M.GT.0 )
-     $         CALL MB04OY( IM, M, A(1,I), TAU(I), B(I,1), LDB, C, LDC,
-     $                      DWORK )
-   10    CONTINUE
-C
-      ELSE
-C
-         DO 20 I = 1, N - 1
-C
-C           Annihilate the I-th column of A and apply the
-C           transformations to the first block column, exploiting its
-C           structure.
-C
-            CALL DLARFG( P+1, R(I,I), A(1,I), 1, TAU(I) )
-C
-C           Compute
-C                           [ R(I,I+1:N) ]
-C           w := [ 1 v' ] * [            ],
-C                           [ A(:,I+1:N) ]
-C
-C           [ R(I,I+1:N) ]    [ R(I,I+1:N) ]         [ 1 ]
-C           [            ] := [            ] - tau * [   ] * w .
-C           [ A(:,I+1:N) ]    [ A(:,I+1:N) ]         [ v ]
-C
-            CALL MB04OY( P, N-I, A(1,I), TAU(I), R(I,I+1), LDR,
-     $                   A(1,I+1), LDA, DWORK )
-   20    CONTINUE
-C
-         CALL DLARFG( P+1, R(N,N), A(1,N), 1, TAU(N) )
-         IF ( M.GT.0 ) THEN
-C
-C           Apply the transformations to the second block column.
-C
-            DO 30 I = 1, N
-C
-C              Compute
-C                              [ B(I,:) ]
-C              w := [ 1 v' ] * [        ],
-C                              [   C    ]
-C
-C              [ B(I,:) ]    [ B(I,:) ]         [ 1 ]
-C              [        ] := [        ] - tau * [   ] * w.
-C              [   C    ]    [   C    ]         [ v ]
-C
-               CALL MB04OY( P, M, A(1,I), TAU(I), B(I,1), LDB, C, LDC,
-     $                      DWORK )
-   30       CONTINUE
-C
-         END IF
-      END IF
-      RETURN
-C *** Last line of MB04OD ***
-      END
--- a/extra/control-devel/src/MB04OX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,106 +0,0 @@
-      SUBROUTINE MB04OX( N, A, LDA, X, INCX )
-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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To perform the QR factorization
-C
-C        (U ) = Q*(R),
-C        (x')     (0)
-C
-C     where U and R are n-by-n upper triangular matrices, x is an
-C     n element vector and Q is an (n+1)-by-(n+1) orthogonal matrix.
-C
-C     U must be supplied in the n-by-n upper triangular part of the
-C     array A and this is overwritten by R.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N      (input) INTEGER
-C            The number of elements of X and the order of the square
-C            matrix A.  N >= 0.
-C
-C     A      (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C            On entry, the leading N-by-N upper triangular part of this
-C            array must contain the upper triangular matrix U.
-C            On exit, the leading N-by-N upper triangular part of this
-C            array contains the upper triangular matrix R.
-C            The strict lower triangle of A is not referenced.
-C
-C     LDA    INTEGER
-C            The leading dimension of the array A.  LDA >= max(1,N).
-C
-C     X      (input/output) DOUBLE PRECISION array, dimension
-C            (1+(N-1)*INCX)
-C            On entry, the incremented array X must contain the
-C            vector x. On exit, the content of X is changed.
-C
-C     INCX   (input) INTEGER.
-C            Specifies the increment for the elements of X.  INCX > 0.
-C
-C     METHOD
-C
-C     The matrix Q is formed as a sequence of plane rotations in planes
-C     (1, n+1), (2, n+1), ..., (n, n+1), the rotation in the (j, n+1)th
-C     plane, Q(j), being chosen to annihilate the jth element of x.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, July 1998.
-C     Based on the RASP routine DUTUPD.
-C
-C     REVISIONS
-C
-C     Nov. 1998, V. Sima, Research Institute for Informatics, Bucharest.
-C
-C     ******************************************************************
-C
-C     .. Scalar Arguments ..
-      INTEGER            INCX, LDA, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A(LDA,*), X(*)
-C     .. Local Scalars ..
-      DOUBLE PRECISION   CI, SI, TEMP
-      INTEGER            I, IX
-C     .. External Subroutines ..
-      EXTERNAL           DLARTG, DROT
-C
-C     .. Executable Statements ..
-C
-C     For efficiency reasons, the parameters are not checked.
-C
-      IX = 1
-C
-      DO 20 I = 1, N - 1
-         CALL DLARTG( A(I,I), X(IX), CI, SI, TEMP )
-         A(I,I) = TEMP
-         IX = IX + INCX
-         CALL DROT( N-I, A(I,I+1), LDA, X(IX), INCX, CI, SI )
-   20 CONTINUE
-C
-      CALL DLARTG( A(N,N), X(IX), CI, SI, TEMP )
-      A(N,N) = TEMP
-C
-      RETURN
-C *** Last line of MB04OX ***
-      END
--- a/extra/control-devel/src/MB04OY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,370 +0,0 @@
-      SUBROUTINE MB04OY( M, N, V, TAU, A, LDA, B, LDB, DWORK )
-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 apply a real elementary reflector H to a real (m+1)-by-n
-C     matrix C = [ A ], from the left, where A has one row. H is
-C                [ B ]
-C     represented in the form
-C                                        ( 1 )
-C           H = I - tau * u *u',    u  = (   ),
-C                                        ( v )
-C     where tau is a real scalar and v is a real m-vector.
-C
-C     If tau = 0, then H is taken to be the unit matrix.
-C
-C     In-line code is used if H has order < 11.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The number of rows of the matrix B.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The number of columns of the matrices A and B.  N >= 0.
-C
-C     V       (input) DOUBLE PRECISION array, dimension (M)
-C             The vector v in the representation of H.
-C
-C     TAU     (input) DOUBLE PRECISION
-C             The scalar factor of the elementary reflector H.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading 1-by-N part of this array must
-C             contain the matrix A.
-C             On exit, the leading 1-by-N part of this array contains
-C             the updated matrix A (the first row of H * C).
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= 1.
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,N)
-C             On entry, the leading M-by-N part of this array must
-C             contain the matrix B.
-C             On exit, the leading M-by-N part of this array contains
-C             the updated matrix B (the last m rows of H * C).
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,M).
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (N)
-C             DWORK is not referenced if H has order less than 11.
-C
-C     METHOD
-C
-C     The routine applies the elementary reflector H, taking the special
-C     structure of C into account.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is backward stable.
-C
-C     CONTRIBUTORS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1997.
-C     Based on LAPACK routines DLARFX and DLATZM.
-C
-C     REVISIONS
-C
-C     Dec. 1997.
-C
-C     KEYWORDS
-C
-C     Elementary matrix operations, elementary reflector, orthogonal
-C     transformation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER           LDA, LDB, M, N
-      DOUBLE PRECISION  TAU
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A( LDA, * ), B( LDB, * ), DWORK( * ), V( * )
-C     .. Local Scalars ..
-      INTEGER           J
-      DOUBLE PRECISION  SUM, T1, T2, T3, T4, T5, T6, T7, T8, T9, V1, V2,
-     $                  V3, V4, V5, V6, V7, V8, V9
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DCOPY, DGEMV, DGER
-C
-C     .. Executable Statements ..
-C
-      IF( TAU.EQ.ZERO )
-     $   RETURN
-C
-C     Form  H * C, where H has order m+1.
-C
-      GO TO ( 10, 30, 50, 70, 90, 110, 130, 150,
-     $        170, 190 ) M+1
-C
-C     Code for general M. Compute
-C
-C     w := C'*u,  C := C - tau * u * w'.
-C
-      CALL DCOPY( N, A, LDA, DWORK, 1 )
-      CALL DGEMV( 'Transpose', M, N, ONE, B, LDB, V, 1, ONE, DWORK, 1 )
-      CALL DAXPY( N, -TAU, DWORK, 1, A, LDA )
-      CALL DGER( M, N, -TAU, V, 1, DWORK, 1, B, LDB )
-      GO TO 210
-   10 CONTINUE
-C
-C     Special code for 1 x 1 Householder
-C
-      T1 = ONE - TAU
-      DO 20 J = 1, N
-         A( 1, J ) = T1*A( 1, J )
-   20 CONTINUE
-      GO TO 210
-   30 CONTINUE
-C
-C     Special code for 2 x 2 Householder
-C
-      V1 = V( 1 )
-      T1 = TAU*V1
-      DO 40 J = 1, N
-         SUM = A( 1, J ) + V1*B( 1, J )
-         A( 1, J ) = A( 1, J ) - SUM*TAU
-         B( 1, J ) = B( 1, J ) - SUM*T1
-   40 CONTINUE
-      GO TO 210
-   50 CONTINUE
-C
-C     Special code for 3 x 3 Householder
-C
-      V1 = V( 1 )
-      T1 = TAU*V1
-      V2 = V( 2 )
-      T2 = TAU*V2
-      DO 60 J = 1, N
-         SUM = A( 1, J ) + V1*B( 1, J ) + V2*B( 2, J )
-         A( 1, J ) = A( 1, J ) - SUM*TAU
-         B( 1, J ) = B( 1, J ) - SUM*T1
-         B( 2, J ) = B( 2, J ) - SUM*T2
-   60 CONTINUE
-      GO TO 210
-   70 CONTINUE
-C
-C     Special code for 4 x 4 Householder
-C
-      V1 = V( 1 )
-      T1 = TAU*V1
-      V2 = V( 2 )
-      T2 = TAU*V2
-      V3 = V( 3 )
-      T3 = TAU*V3
-      DO 80 J = 1, N
-         SUM = A( 1, J ) + V1*B( 1, J ) + V2*B( 2, J ) + V3*B( 3, J )
-         A( 1, J ) = A( 1, J ) - SUM*TAU
-         B( 1, J ) = B( 1, J ) - SUM*T1
-         B( 2, J ) = B( 2, J ) - SUM*T2
-         B( 3, J ) = B( 3, J ) - SUM*T3
-   80 CONTINUE
-      GO TO 210
-   90 CONTINUE
-C
-C     Special code for 5 x 5 Householder
-C
-      V1 = V( 1 )
-      T1 = TAU*V1
-      V2 = V( 2 )
-      T2 = TAU*V2
-      V3 = V( 3 )
-      T3 = TAU*V3
-      V4 = V( 4 )
-      T4 = TAU*V4
-      DO 100 J = 1, N
-         SUM = A( 1, J ) +  V1*B( 1, J ) + V2*B( 2, J ) + V3*B( 3, J ) +
-     $                      V4*B( 4, J )
-         A( 1, J ) = A( 1, J ) - SUM*TAU
-         B( 1, J ) = B( 1, J ) - SUM*T1
-         B( 2, J ) = B( 2, J ) - SUM*T2
-         B( 3, J ) = B( 3, J ) - SUM*T3
-         B( 4, J ) = B( 4, J ) - SUM*T4
-  100 CONTINUE
-      GO TO 210
-  110 CONTINUE
-C
-C     Special code for 6 x 6 Householder
-C
-      V1 = V( 1 )
-      T1 = TAU*V1
-      V2 = V( 2 )
-      T2 = TAU*V2
-      V3 = V( 3 )
-      T3 = TAU*V3
-      V4 = V( 4 )
-      T4 = TAU*V4
-      V5 = V( 5 )
-      T5 = TAU*V5
-      DO 120 J = 1, N
-         SUM = A( 1, J ) +  V1*B( 1, J ) + V2*B( 2, J ) + V3*B( 3, J ) +
-     $                      V4*B( 4, J ) + V5*B( 5, J )
-         A( 1, J ) = A( 1, J ) - SUM*TAU
-         B( 1, J ) = B( 1, J ) - SUM*T1
-         B( 2, J ) = B( 2, J ) - SUM*T2
-         B( 3, J ) = B( 3, J ) - SUM*T3
-         B( 4, J ) = B( 4, J ) - SUM*T4
-         B( 5, J ) = B( 5, J ) - SUM*T5
-  120 CONTINUE
-      GO TO 210
-  130 CONTINUE
-C
-C     Special code for 7 x 7 Householder
-C
-      V1 = V( 1 )
-      T1 = TAU*V1
-      V2 = V( 2 )
-      T2 = TAU*V2
-      V3 = V( 3 )
-      T3 = TAU*V3
-      V4 = V( 4 )
-      T4 = TAU*V4
-      V5 = V( 5 )
-      T5 = TAU*V5
-      V6 = V( 6 )
-      T6 = TAU*V6
-      DO 140 J = 1, N
-         SUM = A( 1, J ) +  V1*B( 1, J ) + V2*B( 2, J ) + V3*B( 3, J ) +
-     $                      V4*B( 4, J ) + V5*B( 5, J ) + V6*B( 6, J )
-         A( 1, J ) = A( 1, J ) - SUM*TAU
-         B( 1, J ) = B( 1, J ) - SUM*T1
-         B( 2, J ) = B( 2, J ) - SUM*T2
-         B( 3, J ) = B( 3, J ) - SUM*T3
-         B( 4, J ) = B( 4, J ) - SUM*T4
-         B( 5, J ) = B( 5, J ) - SUM*T5
-         B( 6, J ) = B( 6, J ) - SUM*T6
-  140 CONTINUE
-      GO TO 210
-  150 CONTINUE
-C
-C     Special code for 8 x 8 Householder
-C
-      V1 = V( 1 )
-      T1 = TAU*V1
-      V2 = V( 2 )
-      T2 = TAU*V2
-      V3 = V( 3 )
-      T3 = TAU*V3
-      V4 = V( 4 )
-      T4 = TAU*V4
-      V5 = V( 5 )
-      T5 = TAU*V5
-      V6 = V( 6 )
-      T6 = TAU*V6
-      V7 = V( 7 )
-      T7 = TAU*V7
-      DO 160 J = 1, N
-         SUM = A( 1, J ) +  V1*B( 1, J ) + V2*B( 2, J ) + V3*B( 3, J ) +
-     $                      V4*B( 4, J ) + V5*B( 5, J ) + V6*B( 6, J ) +
-     $                      V7*B( 7, J )
-         A( 1, J ) = A( 1, J ) - SUM*TAU
-         B( 1, J ) = B( 1, J ) - SUM*T1
-         B( 2, J ) = B( 2, J ) - SUM*T2
-         B( 3, J ) = B( 3, J ) - SUM*T3
-         B( 4, J ) = B( 4, J ) - SUM*T4
-         B( 5, J ) = B( 5, J ) - SUM*T5
-         B( 6, J ) = B( 6, J ) - SUM*T6
-         B( 7, J ) = B( 7, J ) - SUM*T7
-  160 CONTINUE
-      GO TO 210
-  170 CONTINUE
-C
-C     Special code for 9 x 9 Householder
-C
-      V1 = V( 1 )
-      T1 = TAU*V1
-      V2 = V( 2 )
-      T2 = TAU*V2
-      V3 = V( 3 )
-      T3 = TAU*V3
-      V4 = V( 4 )
-      T4 = TAU*V4
-      V5 = V( 5 )
-      T5 = TAU*V5
-      V6 = V( 6 )
-      T6 = TAU*V6
-      V7 = V( 7 )
-      T7 = TAU*V7
-      V8 = V( 8 )
-      T8 = TAU*V8
-      DO 180 J = 1, N
-         SUM = A( 1, J ) +  V1*B( 1, J ) + V2*B( 2, J ) + V3*B( 3, J ) +
-     $                      V4*B( 4, J ) + V5*B( 5, J ) + V6*B( 6, J ) +
-     $                      V7*B( 7, J ) + V8*B( 8, J )
-         A( 1, J ) = A( 1, J ) - SUM*TAU
-         B( 1, J ) = B( 1, J ) - SUM*T1
-         B( 2, J ) = B( 2, J ) - SUM*T2
-         B( 3, J ) = B( 3, J ) - SUM*T3
-         B( 4, J ) = B( 4, J ) - SUM*T4
-         B( 5, J ) = B( 5, J ) - SUM*T5
-         B( 6, J ) = B( 6, J ) - SUM*T6
-         B( 7, J ) = B( 7, J ) - SUM*T7
-         B( 8, J ) = B( 8, J ) - SUM*T8
-  180 CONTINUE
-      GO TO 210
-  190 CONTINUE
-C
-C     Special code for 10 x 10 Householder
-C
-      V1 = V( 1 )
-      T1 = TAU*V1
-      V2 = V( 2 )
-      T2 = TAU*V2
-      V3 = V( 3 )
-      T3 = TAU*V3
-      V4 = V( 4 )
-      T4 = TAU*V4
-      V5 = V( 5 )
-      T5 = TAU*V5
-      V6 = V( 6 )
-      T6 = TAU*V6
-      V7 = V( 7 )
-      T7 = TAU*V7
-      V8 = V( 8 )
-      T8 = TAU*V8
-      V9 = V( 9 )
-      T9 = TAU*V9
-      DO 200 J = 1, N
-         SUM = A( 1, J ) +  V1*B( 1, J ) + V2*B( 2, J ) + V3*B( 3, J ) +
-     $                      V4*B( 4, J ) + V5*B( 5, J ) + V6*B( 6, J ) +
-     $                      V7*B( 7, J ) + V8*B( 8, J ) + V9*B( 9, J )
-         A( 1, J ) = A( 1, J ) - SUM*TAU
-         B( 1, J ) = B( 1, J ) - SUM*T1
-         B( 2, J ) = B( 2, J ) - SUM*T2
-         B( 3, J ) = B( 3, J ) - SUM*T3
-         B( 4, J ) = B( 4, J ) - SUM*T4
-         B( 5, J ) = B( 5, J ) - SUM*T5
-         B( 6, J ) = B( 6, J ) - SUM*T6
-         B( 7, J ) = B( 7, J ) - SUM*T7
-         B( 8, J ) = B( 8, J ) - SUM*T8
-         B( 9, J ) = B( 9, J ) - SUM*T9
-  200 CONTINUE
-  210 CONTINUE
-      RETURN
-C *** Last line of MB04OY ***
-      END
--- a/extra/control-devel/src/MC01PD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,159 +0,0 @@
-      SUBROUTINE MC01PD( K, REZ, IMZ, P, DWORK, 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 coefficients of a real polynomial P(x) from its
-C     zeros.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     K       (input) INTEGER
-C             The number of zeros (and hence the degree) of P(x).
-C             K >= 0.
-C
-C     REZ     (input) DOUBLE PRECISION array, dimension (K)
-C     IMZ     (input) DOUBLE PRECISION array, dimension (K)
-C             The real and imaginary parts of the i-th zero of P(x)
-C             must be stored in REZ(i) and IMZ(i), respectively, where
-C             i = 1, 2, ..., K. The zeros may be supplied in any order,
-C             except that complex conjugate zeros must appear
-C             consecutively.
-C
-C     P       (output) DOUBLE PRECISION array, dimension (K+1)
-C             This array contains the coefficients of P(x) in increasing
-C             powers of x. If K = 0, then P(1) is set to one.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (K+1)
-C             If K = 0, this array is not referenced.
-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             > 0:  if INFO = i, (REZ(i),IMZ(i)) is a complex zero but
-C                   (REZ(i-1),IMZ(i-1)) is not its conjugate.
-C
-C     METHOD
-C
-C     The routine computes the coefficients of the real K-th degree
-C     polynomial P(x) as
-C
-C        P(x) = (x - r(1)) * (x - r(2)) * ... * (x - r(K))
-C
-C     where r(i) = (REZ(i),IMZ(i)).
-C
-C     Note that REZ(i) = REZ(j) and IMZ(i) = -IMZ(j) if r(i) and r(j)
-C     form a complex conjugate pair (where i <> j), and that IMZ(i) = 0
-C     if r(i) is real.
-C
-C     NUMERICAL ASPECTS
-C
-C     None.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Mar. 1997.
-C     Supersedes Release 2.0 routine MC01DD by A.J. Geurts.
-C
-C     REVISIONS
-C
-C     V. Sima, May 2002.
-C
-C     KEYWORDS
-C
-C     Elementary polynomial operations, polynomial operations.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER           INFO, K
-C     .. Array Arguments ..
-      DOUBLE PRECISION  DWORK(*), IMZ(*), P(*), REZ(*)
-C     .. Local Scalars ..
-      INTEGER           I
-      DOUBLE PRECISION  U, V
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DCOPY, XERBLA
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      IF( K.LT.0 ) THEN
-         INFO = -1
-C
-C        Error return.
-C
-         CALL XERBLA( 'MC01PD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      INFO = 0
-      P(1) = ONE
-      IF ( K.EQ.0 )
-     $   RETURN
-C
-      I = 1
-C     WHILE ( I <= K ) DO
-   20 IF ( I.LE.K ) THEN
-         U = REZ(I)
-         V = IMZ(I)
-         DWORK(1) = ZERO
-C
-         IF ( V.EQ.ZERO ) THEN
-            CALL DCOPY( I, P, 1, DWORK(2), 1 )
-            CALL DAXPY( I, -U, P, 1, DWORK, 1 )
-            I = I + 1
-C
-         ELSE
-            IF ( I.EQ.K ) THEN
-               INFO = K
-               RETURN
-            ELSE IF ( ( U.NE.REZ(I+1) ) .OR. ( V.NE.-IMZ(I+1) ) ) THEN
-               INFO = I + 1
-               RETURN
-            END IF
-C
-            DWORK(2) = ZERO
-            CALL DCOPY( I, P, 1, DWORK(3), 1 )
-            CALL DAXPY( I, -(U + U),  P, 1, DWORK(2), 1 )
-            CALL DAXPY( I, U**2+V**2, P, 1, DWORK, 1 )
-            I = I + 2
-         END IF
-C
-         CALL DCOPY( I, DWORK, 1, P, 1 )
-         GO TO 20
-      END IF
-C     END WHILE 20
-C
-      RETURN
-C *** Last line of MC01PD ***
-      END
--- a/extra/control-devel/src/Makefile	Wed Feb 22 15:13:45 2012 +0000
+++ b/extra/control-devel/src/Makefile	Wed Feb 22 16:37:14 2012 +0000
@@ -9,81 +9,56 @@
 #       (__sl*__.oct) would be nice, but this can be an issue
 #       for fortran compilers.
 
+slicotlibrary.a: slicot.tar.gz
+	tar -xzf slicot.tar.gz
+	mv slicot/src/*.f .
+	mv slicot/src_aux/*.f .
+	mkoctfile *.f \
+	${LAPACK_LIBS} ${BLAS_LIBS} ${FLIBS}
+	ar -r slicotlibrary.a *.o
+	rm *.o *.f
+
 # balanced stochastic truncation model reduction
-slab09hd.oct: slab09hd.cc
+slab09hd.oct: slab09hd.cc slicotlibrary.a
 	mkoctfile slab09hd.cc \
-              AB09HD.f TB01ID.f AB04MD.f TB01KD.f AB09HY.f \
-              AB09IX.f MB03UD.f SB02MD.f AB09DD.f TB01LD.f \
-              SB03OU.f MA02AD.f MB03QX.f select.f SB03OT.f \
-              SB02MR.f SB02MS.f MB03QD.f SB02MU.f SB02MV.f \
-              SB02MW.f MB04ND.f MB04OD.f MB03QY.f SB03OR.f \
-              SB03OY.f SB04PX.f MB04NY.f MB04OY.f SB03OV.f \
+              slicotlibrary.a \
               ${LAPACK_LIBS} ${BLAS_LIBS}
 
 # balanced truncation & singular perturbation approximation model reduction
-slab09id.oct: slab09id.cc
+slab09id.oct: slab09id.cc slicotlibrary.a
 	mkoctfile slab09id.cc \
-              AB09ID.f TB01PD.f SB08DD.f TB01ID.f TB01KD.f \
-              AB09IX.f AB09IY.f SB08CD.f MB04ND.f TB01XD.f \
-              MB04OD.f MB01WD.f MB03UD.f AB07MD.f SB01FY.f \
-              AB09DD.f TB01LD.f SB03OU.f TB01UD.f MA02AD.f \
-              MA02BD.f MB03OY.f MB03QX.f MB01PD.f select.f \
-              MB01YD.f MB04NY.f MB01ZD.f SB03OT.f MB04OX.f \
-              MB04OY.f MB03QD.f SB03OY.f MB03QY.f MB01QD.f \
-              SB03OR.f SB03OV.f SB04PX.f \
+              slicotlibrary.a \
               ${LAPACK_LIBS} ${BLAS_LIBS}
 
 # hankel-norm approximation model reduction
-slab09jd.oct: slab09jd.cc
+slab09jd.oct: slab09jd.cc slicotlibrary.a
 	mkoctfile slab09jd.cc \
-              AB09JD.f TB01ID.f TB01KD.f AB07ND.f AB09JV.f \
-              AB09JW.f AB09CX.f AG07BD.f AB08MD.f AB04MD.f \
-              TB01LD.f delctg.f SB04PY.f AB09AX.f AB08NX.f \
-              MB01SD.f AB09JX.f MA02AD.f TB01WD.f MB03OY.f \
-              MB03PY.f MA02DD.f MB03UD.f MB03QX.f select.f \
-              SB04PX.f SB03OU.f MB03QD.f MB03QY.f SB03OT.f \
-              MB04ND.f MB04OD.f SB03OR.f SB03OY.f MB04NY.f \
-              MB04OY.f SB03OV.f \
+              slicotlibrary.a \
               ${LAPACK_LIBS} ${BLAS_LIBS}
 
 # balanced truncation & singular perturbation approximation controller reduction
-slsb16ad.oct: slsb16ad.cc
+slsb16ad.oct: slsb16ad.cc slicotlibrary.a
 	mkoctfile slsb16ad.cc \
-              SB16AD.f TB01ID.f SB16AY.f TB01KD.f AB09IX.f \
-              MB04OD.f MB01WD.f SB03OD.f MB03UD.f AB05PD.f \
-              AB09DD.f AB07ND.f TB01LD.f AB05QD.f SB03OU.f \
-              MA02AD.f MB03QX.f select.f MB01YD.f MB01ZD.f \
-              SB03OT.f MB04OY.f MB03QD.f MB04ND.f MB03QY.f \
-              SB03OR.f SB03OY.f SB04PX.f MB04NY.f SB03OV.f \
+              slicotlibrary.a \
               ${LAPACK_LIBS} ${BLAS_LIBS}	
 
 # coprime factorization state-feedback controller reduction
-slsb16bd.oct: slsb16bd.cc
+slsb16bd.oct: slsb16bd.cc slicotlibrary.a
 	mkoctfile slsb16bd.cc \
-              SB16BD.f AB09AD.f AB09BD.f SB08GD.f SB08HD.f \
-              TB01ID.f AB09AX.f MA02GD.f AB09BX.f TB01WD.f \
-              MA02DD.f MB03UD.f select.f AB09DD.f SB03OU.f \
-              MA02AD.f SB03OT.f MB04ND.f MB04OD.f SB03OR.f \
-              SB03OY.f SB04PX.f MB04NY.f MB04OY.f SB03OV.f \
+              slicotlibrary.a \
               ${LAPACK_LIBS} ${BLAS_LIBS}
 
 # frequency-weighted coprime factorization state-feedback controller reduction
-slsb16cd.oct: slsb16cd.cc
+slsb16cd.oct: slsb16cd.cc slicotlibrary.a
 	mkoctfile slsb16cd.cc \
-              SB16CD.f SB16CY.f AB09IX.f SB03OD.f MB02UD.f \
-              AB09DD.f MA02AD.f MB03UD.f select.f SB03OU.f \
-              MB01SD.f SB03OT.f MB04ND.f MB04OD.f SB03OR.f \
-              SB03OY.f SB04PX.f MB04NY.f MB04OY.f SB03OV.f \
+              slicotlibrary.a \
               ${LAPACK_LIBS} ${BLAS_LIBS}
 
 # fit state-space model to frequency response data
-slsb10yd.oct: slsb10yd.cc
+slsb10yd.oct: slsb10yd.cc slicotlibrary.a
 	mkoctfile slsb10yd.cc \
-              SB10YD.f DG01MD.f AB04MD.f SB10ZP.f AB07ND.f \
-              MC01PD.f TD04AD.f TD03AY.f TB01PD.f TB01XD.f \
-              AB07MD.f TB01UD.f TB01ID.f MB01PD.f MB03OY.f \
-              MB01QD.f \
+              slicotlibrary.a \
               ${LAPACK_LIBS} ${BLAS_LIBS}
 
 clean:
-	rm *.o core octave-core *.oct *~
+	rm -f *.o core octave-core *.oct *~ *.a *.f
--- a/extra/control-devel/src/SB01FY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,315 +0,0 @@
-      SUBROUTINE SB01FY( DISCR, N, M, A, LDA, B, LDB, F, LDF, V, LDV,
-     $                   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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the inner denominator of a right-coprime factorization
-C     of a system of order N, where N is either 1 or 2. Specifically,
-C     given the N-by-N unstable system state matrix A and the N-by-M
-C     system input matrix B, an M-by-N state-feedback matrix F and
-C     an M-by-M matrix V are constructed, such that the system
-C     (A + B*F, B*V, F, V) is inner.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DISCR   LOGICAL
-C             Specifies the type of system as follows:
-C             = .FALSE.:  continuous-time system;
-C             = .TRUE. :  discrete-time system.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix A and also the number of rows of
-C             the matrix B and the number of columns of the matrix F.
-C             N is either 1 or 2.
-C
-C     M       (input) INTEGER
-C             The number of columns of the matrices B and V, and also
-C             the number of rows of the matrix F.  M >= 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 whose eigenvalues must have positive
-C             real parts if DISCR = .FALSE. or moduli greater than unity
-C             if DISCR = .TRUE..
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= 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.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= N.
-C
-C     F       (output) DOUBLE PRECISION array, dimension (LDF,N)
-C             The leading M-by-N part of this array contains the state-
-C             feedback matrix F which assigns one eigenvalue (if N = 1)
-C             or two eigenvalues (if N = 2) of the matrix A + B*F in
-C             symmetric positions with respect to the imaginary axis
-C             (if DISCR = .FALSE.) or the unit circle (if
-C             DISCR = .TRUE.).
-C
-C     LDF     INTEGER
-C             The leading dimension of array F.  LDF >= MAX(1,M).
-C
-C     V       (output) DOUBLE PRECISION array, dimension (LDV,M)
-C             The leading M-by-M upper triangular part of this array
-C             contains the input/output matrix V of the resulting inner
-C             system in upper triangular form.
-C             If DISCR = .FALSE., the resulting V is an identity matrix.
-C
-C     LDV     INTEGER
-C             The leading dimension of array V.  LDF >= MAX(1,M).
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             = 0:  successful exit;
-C             = 1:  if uncontrollability of the pair (A,B) is detected;
-C             = 2:  if A is stable or at the stability limit;
-C             = 3:  if N = 2 and A has a pair of real eigenvalues.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, July 1998.
-C     Based on the RASP routine RCFID2.
-C
-C     REVISIONS
-C
-C     Nov. 1998, V. Sima, Research Institute for Informatics, Bucharest.
-C     Dec. 1998, V. Sima, Katholieke Univ. Leuven, Leuven.
-C     Feb. 1999, A. Varga, DLR Oberpfaffenhofen.
-C
-C     KEYWORDS
-C
-C     Coprime factorization, eigenvalue, eigenvalue assignment,
-C     feedback control, pole placement, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, TWO, ZERO
-      PARAMETER         ( ONE = 1.0D0, TWO = 2.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      LOGICAL           DISCR
-      INTEGER           INFO, LDA, LDB, LDF, LDV, M, N
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), F(LDF,*), V(LDV,*)
-C     .. Local Scalars ..
-      INTEGER           I
-      DOUBLE PRECISION  CS, R11, R12, R22, SCALE, SN, TEMP
-C     .. Local Arrays ..
-      DOUBLE PRECISION  AT(2,2), DUMMY(2,2), U(2,2)
-C     .. External Functions ..
-      DOUBLE PRECISION  DLAPY2, DLAPY3
-      EXTERNAL          DLAPY2, DLAPY3
-C     .. External Subroutines ..
-      EXTERNAL          DLARFG, DLASET, DLATZM, DROTG, DTRTRI, MA02AD,
-     $                  MB04OX, SB03OY
-C     .. Intrinsic Functions ..
-      INTRINSIC         ABS, SQRT
-C     .. Executable Statements ..
-C
-C     For efficiency reasons, the parameters are not checked.
-C
-      INFO = 0
-C
-C     Compute an N-by-N upper triangular R such that R'*R = B*B' and
-C     find an upper triangular matrix U in the equation
-C
-C     A'*U'*U + U'*U*A = R'*R if DISCR = .FALSE. or
-C     A'*U'*U*A - U'*U = R'*R if DISCR = .TRUE. .
-C
-      CALL MA02AD( 'Full', N, M, B, LDB, F, LDF )
-C
-      IF( N.EQ.1 ) THEN
-C
-C        The N = 1 case.
-C
-         IF( M.GT.1 )
-     $      CALL DLARFG( M, F(1,1), F(2,1), 1, TEMP )
-         R11 = ABS( F(1,1) )
-C
-C        Make sure A is unstable or divergent and find U.
-C
-         IF( DISCR ) THEN
-            TEMP = ABS( A(1,1) )
-            IF( TEMP.LE.ONE ) THEN
-               INFO = 2
-               RETURN
-            ELSE
-               TEMP = R11 / SQRT( ( TEMP - ONE )*( TEMP + ONE ) )
-            END IF
-         ELSE
-            IF( A(1,1).LE.ZERO ) THEN
-               INFO = 2
-               RETURN
-            ELSE
-               TEMP = R11 / SQRT( ABS( TWO*A(1,1) ) )
-            END IF
-         END IF
-         U(1,1) = TEMP
-         SCALE  = ONE
-      ELSE
-C
-C        The N = 2 case.
-C
-         IF( M.GT.1 ) THEN
-            CALL DLARFG( M, F(1,1), F(2,1), 1, TEMP )
-            CALL DLATZM( 'Left', M, N-1, F(2,1), 1, TEMP, F(1,2),
-     $                   F(2,2), LDF, V )
-         END IF
-         R11 = F(1,1)
-         R12 = F(1,2)
-         IF( M.GT.2 )
-     $      CALL DLARFG( M-1, F(2,2), F(3,2), 1, TEMP )
-         IF( M.EQ.1 ) THEN
-            R22 = ZERO
-         ELSE
-            R22 = F(2,2)
-         END IF
-         AT(1,1) = A(1,1)
-         AT(1,2) = A(2,1)
-         AT(2,1) = A(1,2)
-         AT(2,2) = A(2,2)
-         U(1,1)  = R11
-         U(1,2)  = R12
-         U(2,2)  = R22
-         CALL SB03OY( DISCR, .FALSE., -1, AT, 2, U, 2, DUMMY, 2,
-     $                SCALE, INFO )
-         IF( INFO.NE.0 ) THEN
-            IF( INFO.NE.4 ) THEN
-               INFO = 2
-            ELSE
-               INFO = 3
-            END IF
-            RETURN
-         END IF
-      END IF
-C
-C     Check the controllability of the pair (A,B).
-C
-C     Warning. Only an exact controllability check is performed.
-C              If the pair (A,B) is nearly uncontrollable, then
-C              the computed results may be inaccurate.
-C
-      DO 10 I = 1, N
-         IF( U(I,I).EQ.ZERO ) THEN
-            INFO = 1
-            RETURN
-         END IF
-   10 CONTINUE
-C
-C     Set V = I.
-C
-      CALL DLASET( 'Upper', M, M, ZERO, ONE, V, LDV )
-C
-      IF( DISCR ) THEN
-C
-C        Compute an upper triangular matrix V such that
-C                                 -1
-C        V*V' = (I+B'*inv(U'*U)*B)  .
-C
-C        First compute F = B'*inv(U) and the Cholesky factorization
-C        of I + F*F'.
-C
-         DO 20 I = 1, M
-            F(I,1) = B(1,I)/U(1,1)*SCALE
-   20    CONTINUE
-         IF( N.EQ.2 ) THEN
-            DO 30 I = 1, M
-               F(I,2) = ( B(2,I) - F(I,1)*U(1,2) )/U(2,2)*SCALE
-   30       CONTINUE
-            CALL MB04OX( M, V, LDV, F(1,2), 1 )
-         END IF
-         CALL MB04OX( M, V, LDV, F(1,1), 1 )
-         CALL DTRTRI( 'Upper', 'NonUnit', M, V, LDV, INFO )
-      END IF
-C
-C     Compute the feedback matrix F as:
-C
-C     1)   If DISCR = .FALSE.
-C
-C             F = -B'*inv(U'*U);
-C
-C     2)   If DISCR = .TRUE.
-C                                -1
-C             F = -B'*(U'*U+B*B')  *A.
-C
-      IF( N.EQ.1 ) THEN
-         IF( DISCR ) THEN
-            TEMP = -A(1,1)
-            R11  = DLAPY2( U(1,1), R11 )
-            DO 40 I = 1, M
-               F(I,1) = ( ( B(1,I)/R11 )/R11 )*TEMP
-   40       CONTINUE
-         ELSE
-            R11 = U(1,1)
-            DO 50 I = 1, M
-               F(I,1) = -( ( B(1,I)/R11 )/R11 )
-   50       CONTINUE
-         END IF
-      ELSE
-C
-C        Set R = U  if DISCR = .FALSE. or compute the Cholesky
-C        factorization of R'*R = U'*U+B*B' if DISCR = .TRUE..
-C
-         IF( DISCR ) THEN
-            TEMP = U(1,1)
-            CALL DROTG( R11, TEMP, CS, SN )
-            TEMP = -SN*R12 + CS*U(1,2)
-            R12  =  CS*R12 + SN*U(1,2)
-            R22  = DLAPY3( R22, TEMP, U(2,2) )
-         ELSE
-            R11 = U(1,1)
-            R12 = U(1,2)
-            R22 = U(2,2)
-         END IF
-C
-C        Compute F = -B'*inv(R'*R).
-C
-         DO 60 I = 1, M
-            F(I,1) = -B(1,I)/R11
-            F(I,2) = -( B(2,I) + F(I,1)*R12 )/R22
-            F(I,2) =  F(I,2)/R22
-            F(I,1) =  ( F(I,1) - F(I,2)*R12 )/R11
-   60    CONTINUE
-         IF( DISCR ) THEN
-C
-C           Compute F <-- F*A.
-C
-            DO 70 I = 1, M
-               TEMP   = F(I,1)*A(1,1) + F(I,2)*A(2,1)
-               F(I,2) = F(I,1)*A(1,2) + F(I,2)*A(2,2)
-               F(I,1) = TEMP
-   70       CONTINUE
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of SB01FY ***
-      END
--- a/extra/control-devel/src/SB02MD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,559 +0,0 @@
-      SUBROUTINE SB02MD( DICO, HINV, UPLO, SCAL, SORT, N, A, LDA, G,
-     $                   LDG, Q, LDQ, RCOND, WR, WI, S, LDS, U, LDU,
-     $                   IWORK, DWORK, LDWORK, BWORK, 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     <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 + X*A - X*B*R  B'*X = 0                            (1)
-C
-C     or the discrete-time algebraic Riccati equation
-C                                        -1
-C        X = A'*X*A - A'*X*B*(R + B'*X*B)  B'*X*A + Q                (2)
-C
-C     where A, B, Q and R are N-by-N, N-by-M, N-by-N and M-by-M matrices
-C     respectively, with Q symmetric and R symmetric nonsingular; X is
-C     an N-by-N symmetric matrix.
-C                       -1
-C     The matrix G = B*R  B' must be provided on input, instead of B and
-C     R, that is, for instance, the continuous-time equation
-C
-C        Q + A'*X + X*A - X*G*X = 0                                  (3)
-C
-C     is solved, where G is an N-by-N symmetric matrix. SLICOT Library
-C     routine SB02MT should be used to compute G, given B and R. SB02MT
-C     also enables to solve Riccati equations corresponding to optimal
-C     problems with coupling terms.
-C
-C     The routine also returns the computed values of the closed-loop
-C     spectrum of the optimal system, i.e., the stable eigenvalues
-C     lambda(1),...,lambda(N) of the corresponding Hamiltonian or
-C     symplectic matrix associated to the optimal problem.
-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 (3), continuous-time case;
-C             = 'D':  Equation (2), discrete-time case.
-C
-C     HINV    CHARACTER*1
-C             If DICO = 'D', specifies which symplectic matrix is to be
-C             constructed, as follows:
-C             = 'D':  The matrix H in (5) (see METHOD) is constructed;
-C             = 'I':  The inverse of the matrix H in (5) is constructed.
-C             HINV is not used if DICO = 'C'.
-C
-C     UPLO    CHARACTER*1
-C             Specifies which triangle of the matrices G and Q is
-C             stored, as follows:
-C             = 'U':  Upper triangle is stored;
-C             = 'L':  Lower triangle is stored.
-C
-C     SCAL    CHARACTER*1
-C             Specifies whether or not a scaling strategy should be
-C             used, as follows:
-C             = 'G':  General scaling should be used;
-C             = 'N':  No scaling should be used.
-C
-C     SORT    CHARACTER*1
-C             Specifies which eigenvalues should be obtained in the top
-C             of the 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 order of the matrices A, Q, G and X.  N >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the coefficient matrix A of the equation.
-C             On exit, if DICO = 'D', and INFO = 0 or INFO > 1, the
-C                                                                    -1
-C             leading N-by-N part of this array contains the matrix A  .
-C             Otherwise, the array A is unchanged on exit.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     G       (input) DOUBLE PRECISION array, dimension (LDG,N)
-C             The leading N-by-N upper triangular part (if UPLO = 'U')
-C             or lower triangular part (if UPLO = 'L') of this array
-C             must contain the upper triangular part or lower triangular
-C             part, respectively, of the symmetric matrix G. The stricly
-C             lower triangular part (if UPLO = 'U') or stricly upper
-C             triangular part (if UPLO = 'L') is not referenced.
-C
-C     LDG     INTEGER
-C             The leading dimension of array G.  LDG >= MAX(1,N).
-C
-C     Q       (input/output) DOUBLE PRECISION array, dimension (LDQ,N)
-C             On entry, the leading N-by-N upper triangular part (if
-C             UPLO = 'U') or lower triangular part (if UPLO = 'L') of
-C             this array must contain the upper triangular part or lower
-C             triangular part, respectively, of the symmetric matrix Q.
-C             The stricly lower triangular part (if UPLO = 'U') or
-C             stricly upper triangular part (if UPLO = 'L') is not used.
-C             On exit, if INFO = 0, the leading N-by-N part of this
-C             array contains the solution matrix X of the problem.
-C
-C     LDQ     INTEGER
-C             The leading dimension of array N.  LDQ >= MAX(1,N).
-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     WR      (output) DOUBLE PRECISION array, dimension (2*N)
-C     WI      (output) DOUBLE PRECISION array, dimension (2*N)
-C             If INFO = 0 or INFO = 5, these arrays contain the real and
-C             imaginary parts, respectively, of the eigenvalues of the
-C             2N-by-2N matrix S, ordered as specified by SORT (except
-C             for the case HINV = 'D', when the order is opposite to
-C             that specified by SORT). The leading N elements of these
-C             arrays contain the closed-loop spectrum of the system
-C                           -1
-C             matrix A - B*R  *B'*X, if DICO = 'C', or of the matrix
-C                               -1
-C             A - B*(R + B'*X*B)  B'*X*A, if DICO = 'D'. Specifically,
-C                lambda(k) = WR(k) + j*WI(k), for k = 1,2,...,N.
-C
-C     S       (output) DOUBLE PRECISION array, dimension (LDS,2*N)
-C             If INFO = 0 or INFO = 5, the leading 2N-by-2N part of this
-C             array contains the ordered real Schur form S of the
-C             Hamiltonian or symplectic matrix H. 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
-C     LDS     INTEGER
-C             The leading dimension of array S.  LDS >= MAX(1,2*N).
-C
-C     U       (output) DOUBLE PRECISION array, dimension (LDU,2*N)
-C             If INFO = 0 or INFO = 5, the leading 2N-by-2N part of this
-C             array contains the transformation matrix U which reduces
-C             the Hamiltonian or symplectic matrix H to the ordered real
-C             Schur form S. 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     Workspace
-C
-C     IWORK   INTEGER array, dimension (2*N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK and DWORK(2) returns the scaling factor used
-C             (set to 1 if SCAL = 'N'), also set if INFO = 5;
-C             if DICO = 'D', DWORK(3) returns the reciprocal condition
-C             number of the given matrix  A.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(2,6*N) if DICO = 'C';
-C             LDWORK >= MAX(3,6*N) if DICO = 'D'.
-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 matrix A is (numerically) singular in discrete-
-C                   time case;
-C             = 2:  if the Hamiltonian or symplectic matrix H cannot be
-C                   reduced to real Schur form;
-C             = 3:  if the real Schur form of the Hamiltonian or
-C                   symplectic matrix H cannot be appropriately ordered;
-C             = 4:  if the Hamiltonian or symplectic matrix H has less
-C                   than N stable eigenvalues;
-C             = 5:  if the N-th order system of linear algebraic
-C                   equations, from which the solution matrix X would
-C                   be obtained, is singular to working precision.
-C
-C     METHOD
-C
-C     The method used is the Schur vector approach proposed by Laub.
-C     It is assumed that [A,B] is a stabilizable pair (where for (3) B
-C     is any matrix such that B*B' = G with rank(B) = rank(G)), and
-C     [E,A] is a detectable pair, where E is any matrix such that
-C     E*E' = Q with rank(E) = rank(Q). Under these assumptions, any of
-C     the algebraic Riccati equations (1)-(3) is known to have a unique
-C     non-negative definite solution. See [2].
-C     Now consider the 2N-by-2N Hamiltonian or symplectic matrix
-C
-C                 ( A   -G )
-C            H =  (        ),                                    (4)
-C                 (-Q   -A'),
-C
-C     for continuous-time equation, and
-C                    -1        -1
-C                 ( A         A  *G   )
-C            H =  (   -1          -1  ),                         (5)
-C                 (Q*A    A' + Q*A  *G)
-C                                                            -1
-C     for discrete-time equation, respectively, where G = B*R  *B'.
-C     The assumptions guarantee that H in (4) has no pure imaginary
-C     eigenvalues, and H in (5) has no eigenvalues on the unit circle.
-C     If Y is an N-by-N matrix then there exists an orthogonal matrix U
-C     such that U'*Y*U is an upper quasi-triangular matrix. Moreover, U
-C     can be chosen so that the 2-by-2 and 1-by-1 diagonal blocks
-C     (corresponding to the complex conjugate eigenvalues and real
-C     eigenvalues respectively) appear in any desired order. This is the
-C     ordered real Schur form. Thus, we can find an orthogonal
-C     similarity transformation U which puts (4) or (5) in ordered real
-C     Schur form
-C
-C            U'*H*U = S = (S(1,1)  S(1,2))
-C                         (  0     S(2,2))
-C
-C     where S(i,j) is an N-by-N matrix and the eigenvalues of S(1,1)
-C     have negative real parts in case of (4), or moduli greater than
-C     one in case of (5). If U is conformably partitioned into four
-C     N-by-N blocks
-C
-C               U = (U(1,1)  U(1,2))
-C                   (U(2,1)  U(2,2))
-C
-C     with respect to the assumptions we then have
-C     (a) U(1,1) is invertible and X = U(2,1)*inv(U(1,1)) solves (1),
-C         (2), or (3) with X = X' and non-negative definite;
-C     (b) the eigenvalues of S(1,1) (if DICO = 'C') or S(2,2) (if
-C         DICO = 'D') are equal to the eigenvalues of optimal system
-C         (the 'closed-loop' spectrum).
-C
-C     [A,B] is stabilizable if there exists a matrix F such that (A-BF)
-C     is stable. [E,A] is detectable if [A',E'] is stabilizable.
-C
-C     REFERENCES
-C
-C     [1] Laub, A.J.
-C         A Schur Method for Solving Algebraic Riccati equations.
-C         IEEE Trans. Auto. Contr., AC-24, pp. 913-921, 1979.
-C
-C     [2] Wonham, W.M.
-C         On a matrix Riccati equation of stochastic control.
-C         SIAM J. Contr., 6, pp. 681-697, 1968.
-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                               3
-C     The algorithm requires 0(N ) operations.
-C
-C     FURTHER COMMENTS
-C
-C     To obtain a stabilizing solution of the algebraic Riccati
-C     equation for DICO = 'D', set SORT = 'U', if HINV = 'D', or set
-C     SORT = 'S', if HINV = 'I'.
-C
-C     The routine can also compute the anti-stabilizing solutions of
-C     the algebraic Riccati equations, by specifying
-C         SORT = 'U' if DICO = 'D' and HINV = 'I', or DICO = 'C', or
-C         SORT = 'S' if DICO = 'D' and HINV = 'D'.
-C
-C     Usually, the combinations HINV = 'D' and SORT = 'U', or HINV = 'I'
-C     and SORT = 'U', will be faster then the other combinations [3].
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Aug. 1997.
-C     Supersedes Release 2.0 routine SB02AD by Control Systems Research
-C     Group, Kingston Polytechnic, United Kingdom, March 1982.
-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
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, HALF, ONE
-      PARAMETER         ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, HINV, SCAL, SORT, UPLO
-      INTEGER           INFO, LDA, LDG, LDQ, LDS, LDU, LDWORK, N
-      DOUBLE PRECISION  RCOND
-C     .. Array Arguments ..
-      LOGICAL           BWORK(*)
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), DWORK(*), G(LDG,*), Q(LDQ,*),
-     $                  S(LDS,*), U(LDU,*), WR(*), WI(*)
-C     .. Local Scalars ..
-      LOGICAL           DISCR, LHINV, LSCAL, LSORT, LUPLO
-      INTEGER           I, IERR, ISCL, N2, NP1, NROT
-      DOUBLE PRECISION  GNORM, QNORM, RCONDA, UNORM, WRKOPT
-C     .. External Functions ..
-      LOGICAL           LSAME, SB02MR, SB02MS, SB02MV, SB02MW
-      DOUBLE PRECISION  DLAMCH, DLANGE, DLANSY
-      EXTERNAL          DLAMCH, DLANGE, DLANSY, LSAME, SB02MR, SB02MS,
-     $                  SB02MV, SB02MW
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DCOPY, DGECON, DGEES, DGETRF, DGETRS,
-     $                  DLACPY, DLASCL, DLASET, DSCAL, DSWAP, SB02MU,
-     $                  XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         INT, MAX
-C     .. Executable Statements ..
-C
-      INFO = 0
-      N2  = N + N
-      NP1 = N + 1
-      DISCR = LSAME( DICO, 'D' )
-      LSCAL = LSAME( SCAL, 'G' )
-      LSORT = LSAME( SORT, 'S' )
-      LUPLO = LSAME( UPLO, 'U' )
-      IF ( DISCR ) LHINV = LSAME( HINV, 'D' )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.DISCR .AND. .NOT.LSAME( DICO, 'C' ) ) THEN
-         INFO = -1
-      ELSE IF( DISCR ) THEN
-         IF( .NOT.LHINV .AND. .NOT.LSAME( HINV, 'I' ) )
-     $      INFO = -2
-      END IF
-      IF( .NOT.LUPLO .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT.LSCAL .AND. .NOT.LSAME( SCAL, 'N' ) ) THEN
-         INFO = -4
-      ELSE IF( .NOT.LSORT .AND. .NOT.LSAME( SORT, 'U' ) ) THEN
-         INFO = -5
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( LDG.LT.MAX( 1, N ) ) THEN
-         INFO = -10
-      ELSE IF( LDQ.LT.MAX( 1, N ) ) THEN
-         INFO = -12
-      ELSE IF( LDS.LT.MAX( 1, N2 ) ) THEN
-         INFO = -17
-      ELSE IF( LDU.LT.MAX( 1, N2 ) ) THEN
-         INFO = -19
-      ELSE IF( ( .NOT.DISCR .AND. LDWORK.LT.MAX( 2, 6*N ) ) .OR.
-     $         (      DISCR .AND. LDWORK.LT.MAX( 3, 6*N ) ) ) THEN
-         INFO = -22
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB02MD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( N.EQ.0 ) THEN
-         RCOND = ONE
-         DWORK(1) = ONE
-         DWORK(2) = ONE
-         IF ( DISCR ) DWORK(3) = ONE
-         RETURN
-      END IF
-C
-      IF ( LSCAL ) THEN
-C
-C        Compute the norms of the matrices Q and G.
-C
-         QNORM = DLANSY( '1-norm', UPLO, N, Q, LDQ, DWORK )
-         GNORM = DLANSY( '1-norm', UPLO, N, G, LDG, DWORK )
-      END IF
-C
-C     Initialise the Hamiltonian or symplectic matrix associated with
-C     the problem.
-C     Workspace:  need   1          if DICO = 'C';
-C                        max(2,4*N) if DICO = 'D';
-C                 prefer larger if DICO = 'D'.
-C
-      CALL SB02MU( DICO, HINV, UPLO, N, A, LDA, G, LDG, Q, LDQ, S, LDS,
-     $             IWORK, DWORK, LDWORK, INFO )
-      IF ( INFO.NE.0 ) THEN
-         INFO = 1
-         RETURN
-      END IF
-C
-      WRKOPT = DWORK(1)
-      IF ( DISCR ) RCONDA = DWORK(2)
-C
-      ISCL = 0
-      IF ( LSCAL ) THEN
-C
-C        Scale the Hamiltonian or symplectic matrix.
-C
-         IF( QNORM.GT.GNORM .AND. GNORM.GT.ZERO ) THEN
-            CALL DLASCL( 'G', 0, 0, QNORM, GNORM, N, N, S(NP1,1), N2,
-     $                   IERR )
-            CALL DLASCL( 'G', 0, 0, GNORM, QNORM, N, N, S(1,NP1), N2,
-     $                   IERR )
-            ISCL = 1
-         END IF
-      END IF
-C
-C     Find the ordered Schur factorization of S,   S = U*H*U'.
-C     Workspace:  need   6*N;
-C                 prefer larger.
-C
-      IF ( .NOT.DISCR ) THEN
-         IF ( LSORT ) THEN
-            CALL DGEES( 'Vectors', 'Sorted', SB02MV, N2, S, LDS, NROT,
-     $                  WR, WI, U, LDU, DWORK, LDWORK, BWORK, INFO )
-         ELSE
-            CALL DGEES( 'Vectors', 'Sorted', SB02MR, N2, S, LDS, NROT,
-     $                  WR, WI, U, LDU, DWORK, LDWORK, BWORK, INFO )
-         END IF
-      ELSE
-         IF ( LSORT ) THEN
-            CALL DGEES( 'Vectors', 'Sorted', SB02MW, N2, S, LDS, NROT,
-     $                  WR, WI, U, LDU, DWORK, LDWORK, BWORK, INFO )
-         ELSE
-            CALL DGEES( 'Vectors', 'Sorted', SB02MS, N2, S, LDS, NROT,
-     $                  WR, WI, U, LDU, DWORK, LDWORK, BWORK, INFO )
-         END IF
-         IF ( LHINV ) THEN
-            CALL DSWAP( N, WR, 1, WR(NP1), 1 )
-            CALL DSWAP( N, WI, 1, WI(NP1), 1 )
-         END IF
-      END IF
-      IF ( INFO.GT.N2 ) THEN
-         INFO = 3
-      ELSE IF ( INFO.GT.0 ) THEN
-         INFO = 2
-      ELSE IF ( NROT.NE.N ) THEN
-         INFO = 4
-      END IF
-      IF ( INFO.NE.0 )
-     $   RETURN
-C
-      WRKOPT = MAX( WRKOPT, DWORK(1) )
-C
-C     Check if U(1,1) is singular.  Use the (2,1) block of S as a
-C     workspace for factoring U(1,1).
-C
-      UNORM = DLANGE( '1-norm', N, N, U, LDU, DWORK )
-C
-      CALL DLACPY( 'Full', N, N, U, LDU, S(NP1,1), LDS )
-      CALL DGETRF( N, N, S(NP1,1), LDS, IWORK, INFO )
-C
-      IF ( INFO.GT.0 ) THEN
-C
-C        Singular matrix.  Set INFO and RCOND for error return.
-C
-         INFO  = 5
-         RCOND = ZERO
-         GO TO 100
-      END IF
-C
-C     Estimate the reciprocal condition of U(1,1).
-C     Workspace: 6*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 = 5
-         RETURN
-      END IF
-C
-C     Transpose U(2,1) in Q and compute the solution.
-C
-      DO 60 I = 1, N
-         CALL DCOPY( N, U(NP1,I), 1, Q(I,1), LDQ )
-   60 CONTINUE
-C
-      CALL DGETRS( 'Transpose', N, N, S(NP1,1), LDS, IWORK, Q, LDQ,
-     $             INFO )
-C
-C     Set S(2,1) to zero.
-C
-      CALL DLASET( 'Full', N, N, ZERO, ZERO, S(NP1,1), LDS )
-C
-C     Make sure the solution matrix X is symmetric.
-C
-      DO 80 I = 1, N - 1
-         CALL DAXPY( N-I, ONE, Q(I,I+1), LDQ, Q(I+1,I), 1 )
-         CALL DSCAL( N-I, HALF, Q(I+1,I), 1 )
-         CALL DCOPY( N-I, Q(I+1,I), 1, Q(I,I+1), LDQ )
-   80 CONTINUE
-C
-      IF( LSCAL ) THEN
-C
-C        Undo scaling for the solution matrix.
-C
-         IF( ISCL.EQ.1 )
-     $      CALL DLASCL( 'G', 0, 0, GNORM, QNORM, N, N, Q, LDQ, IERR )
-      END IF
-C
-C     Set the optimal workspace, the scaling factor, and reciprocal
-C     condition number (if any).
-C
-      DWORK(1) = WRKOPT
-  100 CONTINUE
-      IF( ISCL.EQ.1 ) THEN
-         DWORK(2) = QNORM / GNORM
-      ELSE
-         DWORK(2) = ONE
-      END IF
-      IF ( DISCR ) DWORK(3) = RCONDA
-C
-      RETURN
-C *** Last line of SB02MD ***
-      END
--- a/extra/control-devel/src/SB02MR.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-      LOGICAL FUNCTION SB02MR( REIG, IEIG )
-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 eigenvalues for solving the continuous-time
-C     algebraic Riccati equation.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     REIG    (input) DOUBLE PRECISION
-C             The real part of the current eigenvalue considered.
-C
-C     IEIG    (input) DOUBLE PRECISION
-C             The imaginary part of the current eigenvalue considered.
-C
-C     METHOD
-C
-C     The function value SB02MR 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     V. Sima, Katholieke Univ. Leuven, Belgium, Aug. 1997.
-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
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO
-      PARAMETER         ( ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION  IEIG, REIG
-C     .. Executable Statements ..
-C
-      SB02MR = REIG.GE.ZERO
-C
-      RETURN
-C *** Last line of SB02MR ***
-      END
--- a/extra/control-devel/src/SB02MS.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-      LOGICAL FUNCTION SB02MS( REIG, IEIG )
-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 eigenvalues for solving the discrete-time
-C     algebraic Riccati equation.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     REIG    (input) DOUBLE PRECISION
-C             The real part of the current eigenvalue considered.
-C
-C     IEIG    (input) DOUBLE PRECISION
-C             The imaginary part of the current eigenvalue considered.
-C
-C     METHOD
-C
-C     The function value SB02MS 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     V. Sima, Katholieke Univ. Leuven, Belgium, Aug. 1997.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Algebraic Riccati equation, closed loop system, discrete-time
-C     system, optimal regulator, Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE
-      PARAMETER         ( ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION  IEIG, REIG
-C     .. External Functions ..
-      DOUBLE PRECISION   DLAPY2
-      EXTERNAL           DLAPY2
-C     .. Executable Statements ..
-C
-      SB02MS = DLAPY2( REIG, IEIG ).GE.ONE
-C
-      RETURN
-C *** Last line of SB02MS ***
-      END
--- a/extra/control-devel/src/SB02MT.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,581 +0,0 @@
-      SUBROUTINE SB02MT( JOBG, JOBL, FACT, UPLO, N, M, A, LDA, B, LDB,
-     $                   Q, LDQ, R, LDR, L, LDL, IPIV, OUFACT, G, LDG,
-     $                   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 compute the following matrices
-C
-C                -1
-C         G = B*R  *B',
-C
-C         -          -1
-C         A = A - B*R  *L',
-C
-C         -          -1
-C         Q = Q - L*R  *L',
-C
-C     where A, B, Q, R, L, and G are N-by-N, N-by-M, N-by-N, M-by-M,
-C     N-by-M, and N-by-N matrices, respectively, with Q, R and G
-C     symmetric matrices.
-C
-C     When R is well-conditioned with respect to inversion, standard
-C     algorithms for solving linear-quadratic optimization problems will
-C     then also solve optimization problems with coupling weighting
-C     matrix L. Moreover, a gain in efficiency is possible using matrix
-C     G in the deflating subspace algorithms (see SLICOT Library routine
-C     SB02OD).
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBG    CHARACTER*1
-C             Specifies whether or not the matrix G is to be computed,
-C             as follows:
-C             = 'G':  Compute G;
-C             = 'N':  Do not compute G.
-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
-C     FACT    CHARACTER*1
-C             Specifies how the matrix R is given (factored or not), as
-C             follows:
-C             = 'N':  Array R contains the matrix R;
-C             = 'C':  Array R contains the Cholesky factor of R;
-C             = 'U':  Array R contains the symmetric indefinite UdU' or
-C                     LdL' factorization of R.
-C
-C     UPLO    CHARACTER*1
-C             Specifies which triangle of the matrices R and Q (if
-C             JOBL = 'N') is stored, as follows:
-C             = 'U':  Upper triangle is stored;
-C             = 'L':  Lower triangle is stored.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A, Q, and G, and the number of
-C             rows of the matrices B and L.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The order of the matrix R, and the number of columns of
-C             the matrices B and L.  M >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, if JOBL = 'N', the leading N-by-N part of this
-C             array must contain the matrix A.
-C             On exit, if JOBL = 'N', and INFO = 0, the leading N-by-N
-C                                                    -          -1
-C             part of this array contains the matrix A = A - B*R  L'.
-C             If JOBL = 'Z', this array is not referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.
-C             LDA >= MAX(1,N) if JOBL = 'N';
-C             LDA >= 1        if JOBL = 'Z'.
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the matrix B.
-C             On exit, if OUFACT = 1, and INFO = 0, the leading N-by-M
-C                                                             -1
-C             part of this array contains the matrix B*chol(R)  .
-C             On exit, B is unchanged if OUFACT = 2 (hence also when
-C             FACT = 'U').
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     Q       (input/output) DOUBLE PRECISION array, dimension (LDQ,N)
-C             On entry, if JOBL = 'N', the leading N-by-N upper
-C             triangular part (if UPLO = 'U') or lower triangular part
-C             (if UPLO = 'L') of this array must contain the upper
-C             triangular part or lower triangular part, respectively, of
-C             the symmetric matrix Q. The stricly lower triangular part
-C             (if UPLO = 'U') or stricly upper triangular part (if
-C             UPLO = 'L') is not referenced.
-C             On exit, if JOBL = 'N' and INFO = 0, the leading N-by-N
-C             upper triangular part (if UPLO = 'U') or lower triangular
-C             part (if UPLO = 'L') of this array contains the upper
-C             triangular part or lower triangular part, respectively, of
-C                                  -          -1
-C             the symmetric matrix Q = Q - L*R  *L'.
-C             If JOBL = 'Z', this array is not referenced.
-C
-C     LDQ     INTEGER
-C             The leading dimension of array Q.
-C             LDQ >= MAX(1,N) if JOBL = 'N';
-C             LDQ >= 1        if JOBL = 'Z'.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,M)
-C             On entry, if FACT = 'N', the leading M-by-M upper
-C             triangular part (if UPLO = 'U') or lower triangular part
-C             (if UPLO = 'L') of this array must contain the upper
-C             triangular part or lower triangular part, respectively,
-C             of the symmetric input weighting matrix R.
-C             On entry, if FACT = 'C', the leading M-by-M upper
-C             triangular part (if UPLO = 'U') or lower triangular part
-C             (if UPLO = 'L') of this array must contain the Cholesky
-C             factor of the positive definite input weighting matrix R
-C             (as produced by LAPACK routine DPOTRF).
-C             On entry, if FACT = 'U', the leading M-by-M upper
-C             triangular part (if UPLO = 'U') or lower triangular part
-C             (if UPLO = 'L') of this array must contain the factors of
-C             the UdU' or LdL' factorization, respectively, of the
-C             symmetric indefinite input weighting matrix R (as produced
-C             by LAPACK routine DSYTRF).
-C             If FACT = 'N', the stricly lower triangular part (if UPLO
-C             = 'U') or stricly upper triangular part (if UPLO = 'L') of
-C             this array is used as workspace.
-C             On exit, if OUFACT = 1, and INFO = 0 (or INFO = M+1),
-C             the leading M-by-M upper triangular part (if UPLO = 'U')
-C             or lower triangular part (if UPLO = 'L') of this array
-C             contains the Cholesky factor of the given input weighting
-C             matrix.
-C             On exit, if OUFACT = 2, and INFO = 0 (or INFO = M+1),
-C             the leading M-by-M upper triangular part (if UPLO = 'U')
-C             or lower triangular part (if UPLO = 'L') of this array
-C             contains the factors of the UdU' or LdL' factorization,
-C             respectively, of the given input weighting matrix.
-C             On exit R is unchanged if FACT = 'C' or 'U'.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,M).
-C
-C     L       (input/output) DOUBLE PRECISION array, dimension (LDL,M)
-C             On entry, if JOBL = 'N', the leading N-by-M part of this
-C             array must contain the matrix L.
-C             On exit, if JOBL = 'N', OUFACT = 1, and INFO = 0, the
-C             leading N-by-M part of this array contains the matrix
-C                      -1
-C             L*chol(R)  .
-C             On exit, L is unchanged if OUFACT = 2 (hence also when
-C             FACT = 'U').
-C             L is not referenced if JOBL = 'Z'.
-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'.
-C
-C     IPIV    (input/output) INTEGER array, dimension (M)
-C             On entry, if FACT = 'U', this array must contain details
-C             of the interchanges performed and the block structure of
-C             the d factor in the UdU' or LdL' factorization of matrix R
-C             (as produced by LAPACK routine DSYTRF).
-C             On exit, if OUFACT = 2, this array contains details of
-C             the interchanges performed and the block structure of the
-C             d factor in the UdU' or LdL' factorization of matrix R,
-C             as produced by LAPACK routine DSYTRF.
-C             This array is not referenced if FACT = 'C'.
-C
-C     OUFACT  (output) INTEGER
-C             Information about the factorization finally used.
-C             OUFACT = 1:  Cholesky factorization of R has been used;
-C             OUFACT = 2:  UdU' (if UPLO = 'U') or LdL' (if UPLO = 'L')
-C                          factorization of R has been used.
-C
-C     G       (output) DOUBLE PRECISION array, dimension (LDG,N)
-C             If JOBG = 'G', and INFO = 0, the leading N-by-N upper
-C             triangular part (if UPLO = 'U') or lower triangular part
-C             (if UPLO = 'L') of this array contains the upper
-C             triangular part (if UPLO = 'U') or lower triangular part
-C                                                                 -1
-C             (if UPLO = 'L'), respectively, of the matrix G = B*R  B'.
-C             If JOBG = 'N', this array is not referenced.
-C
-C     LDG     INTEGER
-C             The leading dimension of array G.
-C             LDG >= MAX(1,N) if JOBG = 'G',
-C             LDG >= 1        if JOBG = 'N'.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (M)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK; if FACT = 'N', DWORK(2) contains the reciprocal
-C             condition number of the given matrix R.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 1              if FACT = 'C';
-C             LDWORK >= MAX(2,3*M,N*M) if FACT = 'N';
-C             LDWORK >= MAX(1,N*M)     if FACT = 'U'.
-C             For optimum performance LDWORK should be larger than 3*M,
-C             if FACT = 'N'.
-C             The N*M workspace is not needed for FACT = 'N', if matrix
-C             R is positive definite.
-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             = i:  if the i-th element (1 <= i <= M) of the d factor is
-C                   exactly zero; the UdU' (or LdL') factorization has
-C                   been completed, but the block diagonal matrix d is
-C                   exactly singular;
-C             = M+1:  if the matrix R is numerically singular.
-C
-C     METHOD
-C                            -     -
-C     The matrices G, and/or A and Q are evaluated using the given or
-C     computed symmetric factorization of R.
-C
-C     NUMERICAL ASPECTS
-C
-C     The routine should not be used when R is ill-conditioned.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Sep. 1997.
-C
-C     REVISIONS
-C
-C     -
-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, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         FACT, JOBG, JOBL, UPLO
-      INTEGER           INFO, LDA, LDB, LDG, LDL, LDQ, LDR, LDWORK, M,
-     $                  N, OUFACT
-C     .. Array Arguments ..
-      INTEGER           IPIV(*), IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), DWORK(*), G(LDG,*),
-     $                  L(LDL,*), Q(LDQ,*), R(LDR,*)
-C     .. Local Scalars ..
-      LOGICAL           LFACTA, LFACTC, LFACTU, LJOBG, LJOBL, LUPLOU
-      CHARACTER         TRANS
-      INTEGER           I, J, WRKOPT
-      DOUBLE PRECISION  EPS, RCOND, RNORM
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH, DLANSY
-      EXTERNAL          DLAMCH, DLANSY, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DCOPY, DGEMM, DGEMV, DPOCON, DPOTRF, DSYCON,
-     $                  DSYRK, DSYTRF, DSYTRS, DTRSM, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         INT, MAX
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      LJOBG  = LSAME( JOBG, 'G' )
-      LJOBL  = LSAME( JOBL, 'N' )
-      LFACTC = LSAME( FACT, 'C' )
-      LFACTU = LSAME( FACT, 'U' )
-      LUPLOU = LSAME( UPLO, 'U' )
-      LFACTA = LFACTC.OR.LFACTU
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.LJOBG .AND. .NOT.LSAME( JOBG, 'N' ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.LJOBL .AND. .NOT.LSAME( JOBL, 'Z' ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.LFACTA .AND. .NOT.LSAME( FACT, 'N' ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT.LUPLOU .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( ( LDA.LT.1 ) .OR. ( LJOBL .AND. LDA.LT.N ) ) THEN
-         INFO = -8
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -10
-      ELSE IF( ( LDQ.LT.1 ) .OR. ( LJOBL .AND. LDQ.LT.N ) ) THEN
-         INFO = -12
-      ELSE IF( LDR.LT.MAX( 1, M ) ) THEN
-         INFO = -14
-      ELSE IF( ( LDL.LT.1 ) .OR. ( LJOBL .AND. LDL.LT.N ) ) THEN
-         INFO = -16
-      ELSE IF( ( LDG.LT.1 ) .OR. ( LJOBG .AND. LDG.LT.N ) ) THEN
-         INFO = -20
-      ELSE IF( ( LFACTC .AND. LDWORK.LT.1 ) .OR.
-     $         ( LFACTU .AND. LDWORK.LT.MAX( 1, N*M ) ) .OR.
-     $    ( .NOT.LFACTA .AND. LDWORK.LT.MAX( 2, N*M, 3*M ) ) ) THEN
-         INFO = -23
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB02MT', -INFO )
-         RETURN
-      END IF
-C
-      IF ( LFACTC ) THEN
-         OUFACT = 1
-      ELSE IF ( LFACTU ) THEN
-         OUFACT = 2
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( N.EQ.0 .OR. M.EQ.0 .OR. .NOT.( LJOBL.OR.LJOBG ) ) THEN
-        DWORK(1) = ONE
-        IF ( .NOT.LFACTA ) DWORK(2) = ONE
-        RETURN
-      END IF
-C
-C     (Note: Comments in the code beginning "Workspace:" describe the
-C     minimal amount of workspace needed at that point in the code,
-C     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
-      WRKOPT = 1
-C
-C     Set relative machine precision.
-C
-      EPS = DLAMCH( 'Epsilon' )
-C
-      IF ( .NOT.LFACTA ) THEN
-C
-C        Compute the norm of the matrix R, which is not factored.
-C        Then save the given triangle of R in the other strict triangle
-C        and the diagonal in the workspace, and try Cholesky
-C        factorization.
-C        Workspace: need M.
-C
-         RNORM = DLANSY( '1-norm', UPLO, M, R, LDR, DWORK )
-         CALL DCOPY( M, R, LDR+1, DWORK, 1 )
-         IF( LUPLOU ) THEN
-C
-            DO 20 J = 2, M
-               CALL DCOPY( J-1, R(1,J), 1, R(J,1), LDR )
-   20       CONTINUE
-C
-         ELSE
-C
-            DO 40 J = 2, M
-               CALL DCOPY( J-1, R(J,1), LDR, R(1,J), 1 )
-   40       CONTINUE
-C
-         END IF
-         CALL DPOTRF( UPLO, M, R, LDR, INFO )
-         IF( INFO.EQ.0 ) THEN
-C
-C           Compute the reciprocal of the condition number of R.
-C           Workspace: need 3*M.
-C
-            CALL DPOCON( UPLO, M, R, LDR, RNORM, RCOND, DWORK, IWORK,
-     $                   INFO )
-C
-C           Return if the matrix is singular to working precision.
-C
-            OUFACT = 1
-            DWORK(2) = RCOND
-            IF( RCOND.LT.EPS ) THEN
-               INFO = M + 1
-               RETURN
-            END IF
-            WRKOPT = MAX( WRKOPT, 3*M )
-         ELSE
-C
-C           Use UdU' or LdL' factorization, first restoring the saved
-C           triangle.
-C
-            CALL DCOPY( M, DWORK, 1, R, LDR+1 )
-            IF( LUPLOU ) THEN
-C
-               DO 60 J = 2, M
-                  CALL DCOPY( J-1, R(J,1), LDR, R(1,J), 1 )
-   60          CONTINUE
-C
-            ELSE
-C
-               DO 80 J = 2, M
-                  CALL DCOPY( J-1, R(1,J), 1, R(J,1), LDR )
-   80          CONTINUE
-C
-            END IF
-C
-C           Compute the UdU' or LdL' factorization.
-C           Workspace: need   1,
-C                      prefer M*NB.
-C
-            CALL DSYTRF( UPLO, M, R, LDR, IPIV, DWORK, LDWORK, INFO )
-            OUFACT = 2
-            IF( INFO.GT.0 ) THEN
-               DWORK(2) = ONE
-               RETURN
-            END IF
-            WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) )
-C
-C           Compute the reciprocal of the condition number of R.
-C           Workspace: need 2*M.
-C
-            CALL DSYCON( UPLO, M, R, LDR, IPIV, RNORM, RCOND, DWORK,
-     $                   IWORK, INFO )
-C
-C           Return if the matrix is singular to working precision.
-C
-            DWORK(2) = RCOND
-            IF( RCOND.LT.EPS ) THEN
-               INFO = M + 1
-               RETURN
-            END IF
-         END IF
-      END IF
-C
-      IF (OUFACT.EQ.1 ) THEN
-C
-C        Solve positive definite linear system(s).
-C
-         IF ( LUPLOU ) THEN
-            TRANS = 'N'
-         ELSE
-            TRANS = 'T'
-         END IF
-C
-C        Solve the system X*U = B, overwriting B with X.
-C
-         CALL DTRSM( 'Right', UPLO, TRANS, 'Non-unit', N, M,
-     $               ONE, R, LDR, B, LDB )
-C
-         IF ( LJOBG ) THEN
-C                                      -1
-C           Compute the matrix  G = B*R  *B', multiplying X*X' in G.
-C
-            CALL DSYRK( UPLO, 'No transpose', N, M, ONE, B, LDB, ZERO,
-     $                  G, LDG )
-         END IF
-C
-         IF( LJOBL ) THEN
-C
-C           Update matrices A and Q.
-C
-C           Solve the system Y*U = L, overwriting L with Y.
-C
-            CALL DTRSM( 'Right', UPLO, TRANS, 'Non-unit', N, M,
-     $                  ONE, R, LDR, L, LDL )
-C
-C           Compute A <- A - X*Y'.
-C
-            CALL DGEMM( 'No transpose', 'Transpose', N, N, M, -ONE, B,
-     $                  LDB, L, LDL, ONE, A, LDA )
-C
-C           Compute Q <- Q - Y*Y'.
-C
-            CALL DSYRK( UPLO, 'No transpose', N, M, -ONE, L, LDL, ONE,
-     $                  Q, LDQ )
-         END IF
-      ELSE
-C
-C        Solve indefinite linear system(s).
-C
-C        Solve the system UdU'*X = B' (or LdL'*X = B').
-C        Workspace: need N*M.
-C
-         DO 100 J = 1, M
-            CALL DCOPY( N, B(1,J), 1, DWORK(J), M )
-  100    CONTINUE
-C
-         CALL DSYTRS( UPLO, M, N, R, LDR, IPIV, DWORK, M, INFO )
-C
-         IF ( LJOBG ) THEN
-C                                                    -1
-C           Compute a triangle of the matrix  G = B*R  *B' = B*X.
-C
-            IF ( LUPLOU ) THEN
-               I = 1
-C
-               DO 120 J = 1, N
-                  CALL DGEMV( 'No transpose', J, M, ONE, B, LDB,
-     $                        DWORK(I), 1, ZERO, G(1,J), 1 )
-                  I = I + M
-  120          CONTINUE
-C
-            ELSE
-C
-               DO 140 J = 1, N
-                  CALL DGEMV( 'Transpose', M, J, ONE, DWORK, M, B(J,1),
-     $                        LDB, ZERO, G(J,1), LDG )
-  140          CONTINUE
-C
-            END IF
-         END IF
-C
-         IF( LJOBL ) THEN
-C
-C           Update matrices A and Q.
-C
-C           Solve the system UdU'*Y = L' (or LdL'*Y = L').
-C
-            DO 160 J = 1, M
-               CALL DCOPY( N, L(1,J), 1, DWORK(J), M )
-  160       CONTINUE
-C
-            CALL DSYTRS( UPLO, M, N, R, LDR, IPIV, DWORK, M, INFO )
-C
-C           A <- A - B*Y.
-C
-            CALL DGEMM( 'No transpose', 'No transpose', N, N, M, -ONE,
-     $                  B, LDB, DWORK, M, ONE, A, LDA )
-C                                            -          -1
-C           Compute a triangle of the matrix Q = Q - L*R  *L' = Q - L*Y.
-C
-            IF ( LUPLOU ) THEN
-               I = 1
-C
-               DO 180 J = 1, N
-                  CALL DGEMV( 'No transpose', J, M, -ONE, L, LDL,
-     $                        DWORK(I), 1, ONE, Q(1,J), 1 )
-                  I = I + M
-  180          CONTINUE
-C
-            ELSE
-C
-               DO 200 J = 1, N
-                  CALL DGEMV( 'Transpose', M, J, -ONE, DWORK, M, L(J,1),
-     $                        LDL, ONE, Q(J,1), LDQ )
-  200          CONTINUE
-C
-            END IF
-         END IF
-      END IF
-C
-      DWORK(1) = WRKOPT
-      IF ( .NOT.LFACTA ) DWORK(2) = RCOND
-C
-C *** Last line of SB02MT ***
-      RETURN
-      END
--- a/extra/control-devel/src/SB02MU.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,486 +0,0 @@
-      SUBROUTINE SB02MU( DICO, HINV, UPLO, N, A, LDA, G, LDG, Q, LDQ, S,
-     $                   LDS, IWORK, DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To construct the 2n-by-2n Hamiltonian or symplectic matrix S
-C     associated to the linear-quadratic optimization problem, used to
-C     solve the continuous- or discrete-time algebraic Riccati equation,
-C     respectively.
-C
-C     For a continuous-time problem, S is defined by
-C
-C             (  A  -G )
-C         S = (        ),                                       (1)
-C             ( -Q  -A')
-C
-C     and for a discrete-time problem by
-C
-C                 -1       -1
-C             (  A        A  *G     )
-C         S = (   -1           -1   ),                          (2)
-C             ( QA     A' + Q*A  *G )
-C
-C     or
-C
-C                       -T         -T
-C             (  A + G*A  *Q   -G*A   )
-C         S = (      -T            -T ),                        (3)
-C             (    -A  *Q         A   )
-C
-C     where A, G, and Q are N-by-N matrices, with G and Q symmetric.
-C     Matrix A must be nonsingular in the discrete-time case.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the system as follows:
-C             = 'C':  Continuous-time system;
-C             = 'D':  Discrete-time system.
-C
-C     HINV    CHARACTER*1
-C             If DICO = 'D', specifies which of the matrices (2) or (3)
-C             is constructed, as follows:
-C             = 'D':  The matrix S in (2) is constructed;
-C             = 'I':  The (inverse) matrix S in (3) is constructed.
-C             HINV is not referenced if DICO = 'C'.
-C
-C     UPLO    CHARACTER*1
-C             Specifies which triangle of the matrices G and Q is
-C             stored, as follows:
-C             = 'U':  Upper triangle is stored;
-C             = 'L':  Lower triangle is stored.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A, G, and Q.  N >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the matrix A.
-C             On exit, if DICO = 'D', and INFO = 0, the leading N-by-N
-C                                                     -1
-C             part of this array contains the matrix A  .
-C             Otherwise, the array A is unchanged on exit.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     G       (input) DOUBLE PRECISION array, dimension (LDG,N)
-C             The leading N-by-N upper triangular part (if UPLO = 'U')
-C             or lower triangular part (if UPLO = 'L') of this array
-C             must contain the upper triangular part or lower triangular
-C             part, respectively, of the symmetric matrix G. The stricly
-C             lower triangular part (if UPLO = 'U') or stricly upper
-C             triangular part (if UPLO = 'L') is not referenced.
-C
-C     LDG     INTEGER
-C             The leading dimension of array G.  LDG >= MAX(1,N).
-C
-C     Q       (input) DOUBLE PRECISION array, dimension (LDQ,N)
-C             The leading N-by-N upper triangular part (if UPLO = 'U')
-C             or lower triangular part (if UPLO = 'L') of this array
-C             must contain the upper triangular part or lower triangular
-C             part, respectively, of the symmetric matrix Q. The stricly
-C             lower triangular part (if UPLO = 'U') or stricly upper
-C             triangular part (if UPLO = 'L') is not referenced.
-C
-C     LDQ     INTEGER
-C             The leading dimension of array Q.  LDQ >= MAX(1,N).
-C
-C     S       (output) DOUBLE PRECISION array, dimension (LDS,2*N)
-C             If INFO = 0, the leading 2N-by-2N part of this array
-C             contains the Hamiltonian or symplectic matrix of the
-C             problem.
-C
-C     LDS     INTEGER
-C             The leading dimension of array S.  LDS >= MAX(1,2*N).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (2*N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK; if DICO = 'D', DWORK(2) returns the reciprocal
-C             condition number of the given matrix  A.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 1          if DICO = 'C';
-C             LDWORK >= MAX(2,4*N) if DICO = 'D'.
-C             For optimum performance LDWORK should be larger, if
-C             DICO = 'D'.
-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             = i:  if the leading i-by-i (1 <= i <= N) upper triangular
-C                   submatrix of A is singular in discrete-time case;
-C             = N+1:  if matrix A is numerically singular in discrete-
-C                   time case.
-C
-C     METHOD
-C
-C     For a continuous-time problem, the 2n-by-2n Hamiltonian matrix (1)
-C     is constructed.
-C     For a discrete-time problem, the 2n-by-2n symplectic matrix (2) or
-C     (3) - the inverse of the matrix in (2) - is constructed.
-C
-C     NUMERICAL ASPECTS
-C
-C     The discrete-time case needs the inverse of the matrix A, hence
-C     the routine should not be used when A is ill-conditioned.
-C                               3
-C     The algorithm requires 0(n ) floating point operations in the
-C     discrete-time case.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Aug. 1997.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Feb. 2004.
-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, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, HINV, UPLO
-      INTEGER           INFO, LDA, LDG, LDQ, LDS, LDWORK, N
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), DWORK(*), G(LDG,*), Q(LDQ,*),
-     $                  S(LDS,*)
-C     .. Local Scalars ..
-      LOGICAL           DISCR, LHINV, LUPLO
-      INTEGER           I, J, MAXWRK, N2, NJ, NP1
-      DOUBLE PRECISION  ANORM, RCOND
-C     .. External Functions ..
-      LOGICAL           LSAME
-      INTEGER           ILAENV
-      DOUBLE PRECISION  DLAMCH, DLANGE
-      EXTERNAL          DLAMCH, DLANGE, ILAENV, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DCOPY, DGECON, DGEMM, DGETRF, DGETRI, DGETRS,
-     $                  DLACPY, DSWAP, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX
-C     .. Executable Statements ..
-C
-      INFO  = 0
-      N2 = N + N
-      DISCR = LSAME( DICO,  'D' )
-      LUPLO = LSAME( UPLO,  'U' )
-      IF( DISCR ) THEN
-         LHINV = LSAME( HINV, 'D' )
-      ELSE
-         LHINV = .FALSE.
-      END IF
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.DISCR .AND. .NOT.LSAME( DICO, 'C' ) ) THEN
-         INFO = -1
-      ELSE IF( DISCR ) THEN
-         IF( .NOT.LHINV .AND. .NOT.LSAME( HINV, 'I' ) )
-     $      INFO = -2
-      END IF
-      IF( .NOT.LUPLO .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDG.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( LDQ.LT.MAX( 1, N ) ) THEN
-         INFO = -10
-      ELSE IF( LDS.LT.MAX( 1, N2 ) ) THEN
-         INFO = -12
-      ELSE IF( ( LDWORK.LT.1 ) .OR.
-     $         ( DISCR .AND. LDWORK.LT.MAX( 2, 4*N ) ) ) THEN
-         INFO = -15
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB02MU', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( N.EQ.0 ) THEN
-         DWORK(1) = ONE
-         IF ( DISCR ) DWORK(2) = ONE
-         RETURN
-      END IF
-C
-C     The code tries to exploit data locality as much as possible.
-C
-      IF ( .NOT.LHINV ) THEN
-         CALL DLACPY( 'Full', N, N, A, LDA, S, LDS )
-C
-C        Construct Hamiltonian matrix in the continuous-time case, or
-C        prepare symplectic matrix in (3) in the discrete-time case:
-C
-C        Construct full Q in S(N+1:2*N,1:N) and change the sign, and
-C        construct full G in S(1:N,N+1:2*N) and change the sign.
-C
-         DO 200 J = 1, N
-            NJ = N + J
-            IF ( LUPLO ) THEN
-C
-               DO 20 I = 1, J
-                  S(N+I,J) = -Q(I,J)
-   20          CONTINUE
-C
-               DO 40 I = J + 1, N
-                  S(N+I,J) = -Q(J,I)
-   40          CONTINUE
-C
-               DO 60 I = 1, J
-                  S(I,NJ) = -G(I,J)
-   60          CONTINUE
-C
-               DO 80 I = J + 1, N
-                  S(I,NJ) = -G(J,I)
-   80          CONTINUE
-C
-            ELSE
-C
-               DO 100 I = 1, J - 1
-                  S(N+I,J) = -Q(J,I)
-  100          CONTINUE
-C
-               DO 120 I = J, N
-                  S(N+I,J) = -Q(I,J)
-  120          CONTINUE
-C
-               DO 140 I = 1, J - 1
-                  S(I,NJ) = -G(J,I)
-  140          CONTINUE
-C
-               DO 180 I = J, N
-                  S(I,NJ) = -G(I,J)
-  180          CONTINUE
-C
-            END IF
-  200    CONTINUE
-C
-         IF ( .NOT.DISCR ) THEN
-C
-            DO 240 J = 1, N
-               NJ = N + J
-C
-               DO 220 I = 1, N
-                  S(N+I,NJ) = -A(J,I)
-  220          CONTINUE
-C
-  240       CONTINUE
-C
-            DWORK(1) = ONE
-         END IF
-      END IF
-C
-      IF ( DISCR ) THEN
-C
-C        Construct the symplectic matrix (2) or (3) in the discrete-time
-C        case.
-C
-C        Compute workspace.
-C        (Note: Comments in the code beginning "Workspace:" describe the
-C        minimal amount of workspace needed at that point in the code,
-C        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
-         MAXWRK = MAX( 4*N,
-     $                 N*ILAENV( 1, 'DGETRI', ' ', N, -1, -1, -1 ) )
-         NP1 = N + 1
-C
-         IF ( LHINV ) THEN
-C
-C           Put  A'  in  S(N+1:2*N,N+1:2*N).
-C
-            DO 260 I = 1, N
-               CALL DCOPY( N, A(I, 1), LDA, S(NP1,N+I), 1 )
-  260       CONTINUE
-C
-         END IF
-C
-C        Compute the norm of the matrix A.
-C
-         ANORM = DLANGE( '1-norm', N, N, A, LDA, DWORK )
-C
-C        Compute the LU factorization of A.
-C
-         CALL DGETRF( N, N, A, LDA, IWORK, INFO )
-C
-C        Return if INFO is non-zero.
-C
-         IF( INFO.GT.0 ) THEN
-            DWORK(2) = ZERO
-            RETURN
-         END IF
-C
-C        Compute the reciprocal of the condition number of A.
-C        Workspace: need 4*N.
-C
-         CALL DGECON( '1-norm', N, A, LDA, ANORM, RCOND, DWORK,
-     $                IWORK(NP1), INFO )
-C
-C        Return if the matrix is singular to working precision.
-C
-         IF( RCOND.LT.DLAMCH( 'Epsilon' ) ) THEN
-            INFO = N + 1
-            DWORK(2) = RCOND
-            RETURN
-         END IF
-C
-         IF ( LHINV ) THEN
-C
-C           Compute S in (2).
-C
-C           Construct full Q in S(N+1:2*N,1:N).
-C
-            IF ( LUPLO ) THEN
-               DO 270 J = 1, N - 1
-                  CALL DCOPY( J, Q(1,J), 1, S(NP1,J), 1 )
-                  CALL DCOPY( N-J, Q(J,J+1), LDQ, S(NP1+J,J), 1 )
-  270          CONTINUE
-               CALL DCOPY( N, Q(1,N), 1, S(NP1,N), 1 )
-            ELSE
-               CALL DCOPY( N, Q(1,1), 1, S(NP1,1), 1 )
-               DO 280 J = 2, N
-                  CALL DCOPY( J-1, Q(J,1), LDQ, S(NP1,J), 1 )
-                  CALL DCOPY( N-J+1, Q(J,J), 1, S(N+J,J), 1 )
-  280          CONTINUE
-            END IF
-C
-C           Compute the solution matrix  X  of the system  X*A = Q  by
-C                                                                    -1
-C           solving  A'*X' = Q and transposing the result to get  Q*A  .
-C
-            CALL DGETRS( 'Transpose', N, N, A, LDA, IWORK, S(NP1,1),
-     $                   LDS, INFO )
-C
-            DO 300 J = 1, N - 1
-               CALL DSWAP( N-J, S(NP1+J,J), 1, S(N+J,J+1), LDS )
-  300       CONTINUE
-C
-C           Construct full G in S(1:N,N+1:2*N).
-C
-            IF ( LUPLO ) THEN
-               DO 310 J = 1, N - 1
-                  CALL DCOPY( J, G(1,J), 1, S(1,N+J), 1 )
-                  CALL DCOPY( N-J, G(J,J+1), LDG, S(J+1,N+J), 1 )
-  310          CONTINUE
-               CALL DCOPY( N, G(1,N), 1, S(1,N2), 1 )
-            ELSE
-               CALL DCOPY( N, G(1,1), 1, S(1,NP1), 1 )
-               DO 320 J = 2, N
-                  CALL DCOPY( J-1, G(J,1), LDG, S(1,N+J), 1 )
-                  CALL DCOPY( N-J+1, G(J,J), 1, S(J,N+J), 1 )
-  320          CONTINUE
-            END IF
-C                            -1
-C           Compute  A' + Q*A  *G  in  S(N+1:2N,N+1:2N).
-C
-            CALL DGEMM( 'No transpose', 'No transpose', N, N, N, ONE,
-     $                  S(NP1,1), LDS, S(1,NP1), LDS, ONE, S(NP1,NP1),
-     $                  LDS )
-C
-C           Compute the solution matrix  Y  of the system  A*Y = G.
-C
-            CALL DGETRS( 'No transpose', N, N, A, LDA, IWORK, S(1,NP1),
-     $                   LDS, INFO )
-C
-C           Compute the inverse of  A  in situ.
-C           Workspace: need N;  prefer N*NB.
-C
-            CALL DGETRI( N, A, LDA, IWORK, DWORK, LDWORK, INFO )
-C                  -1
-C           Copy  A    in  S(1:N,1:N).
-C
-            CALL DLACPY( 'Full', N, N, A, LDA, S, LDS )
-C
-         ELSE
-C
-C           Compute S in (3) using the already prepared part.
-C
-C           Compute the solution matrix  X'  of the system  A*X' = -G
-C                                                       -T
-C           and transpose the result to obtain  X = -G*A  .
-C
-            CALL DGETRS( 'No transpose', N, N, A, LDA, IWORK, S(1,NP1),
-     $                   LDS, INFO )
-C
-            DO 340 J = 1, N - 1
-               CALL DSWAP( N-J, S(J+1,N+J), 1, S(J,NP1+J), LDS )
-  340       CONTINUE
-C                           -T
-C           Compute  A + G*A  *Q  in  S(1:N,1:N).
-C
-            CALL DGEMM( 'No transpose', 'No transpose', N, N, N, ONE,
-     $                  S(1,NP1), LDS, S(NP1, 1), LDS, ONE, S, LDS )
-C
-C           Compute the solution matrix  Y  of the system  A'*Y = -Q.
-C
-            CALL DGETRS( 'Transpose', N, N, A, LDA, IWORK, S(NP1,1),
-     $                   LDS, INFO )
-C
-C           Compute the inverse of  A  in situ.
-C           Workspace: need N;  prefer N*NB.
-C
-            CALL DGETRI( N, A, LDA, IWORK, DWORK, LDWORK, INFO )
-C                  -T
-C           Copy  A    in  S(N+1:2N,N+1:2N).
-C
-            DO 360 J = 1, N
-               CALL DCOPY( N, A(J,1), LDA, S(NP1,N+J), 1 )
-  360       CONTINUE
-C
-         END IF
-         DWORK(1) = MAXWRK
-         DWORK(2) = RCOND
-      END IF
-C
-C *** Last line of SB02MU ***
-      RETURN
-      END
--- a/extra/control-devel/src/SB02MV.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,75 +0,0 @@
-      LOGICAL FUNCTION SB02MV( REIG, IEIG )
-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 eigenvalues for solving the continuous-time
-C     algebraic Riccati equation.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     REIG    (input) DOUBLE PRECISION
-C             The real part of the current eigenvalue considered.
-C
-C     IEIG    (input) DOUBLE PRECISION
-C             The imaginary part of the current eigenvalue considered.
-C
-C     METHOD
-C
-C     The function value SB02MV 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     V. Sima, Katholieke Univ. Leuven, Belgium, Aug. 1997.
-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
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO
-      PARAMETER         ( ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION  IEIG, REIG
-C     .. Executable Statements ..
-C
-      SB02MV = REIG.LT.ZERO
-C
-      RETURN
-C *** Last line of SB02MV ***
-      END
--- a/extra/control-devel/src/SB02MW.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-      LOGICAL FUNCTION SB02MW( REIG, IEIG )
-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 eigenvalues for solving the discrete-time
-C     algebraic Riccati equation.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     REIG    (input) DOUBLE PRECISION
-C             The real part of the current eigenvalue considered.
-C
-C     IEIG    (input) DOUBLE PRECISION
-C             The imaginary part of the current eigenvalue considered.
-C
-C     METHOD
-C
-C     The function value SB02MW is set to .TRUE. for a stable
-C     eigenvalue (i.e., with modulus less than one) and to .FALSE.,
-C     otherwise.
-C
-C     REFERENCES
-C
-C     None.
-C
-C     NUMERICAL ASPECTS
-C
-C     None.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Aug. 1997.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Algebraic Riccati equation, closed loop system, discrete-time
-C     system, optimal regulator, Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE
-      PARAMETER         ( ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION  IEIG, REIG
-C     .. External Functions ..
-      DOUBLE PRECISION   DLAPY2
-      EXTERNAL           DLAPY2
-C     .. Executable Statements ..
-C
-      SB02MW = DLAPY2( REIG, IEIG ).LT.ONE
-C
-      RETURN
-C *** Last line of SB02MW ***
-      END
--- a/extra/control-devel/src/SB02ND.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,755 +0,0 @@
-      SUBROUTINE SB02ND( DICO, FACT, UPLO, JOBL, N, M, P, A, LDA, B,
-     $                   LDB, R, LDR, IPIV, L, LDL, X, LDX, RNORM, F,
-     $                   LDF, OUFACT, 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 compute the optimal feedback matrix F for the problem of
-C     optimal control given by
-C
-C                        -1
-C          F = (R + B'XB)  (B'XA + L')                           (1)
-C
-C     in the discrete-time case and
-C
-C               -1
-C          F = R  (B'X + L')                                     (2)
-C
-C     in the continuous-time case, where A, B and L are N-by-N, N-by-M
-C     and N-by-M matrices respectively; R and X are M-by-M and N-by-N
-C     symmetric matrices respectively.
-C
-C     Optionally, matrix R may be specified in a factored form, and L
-C     may be zero.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the equation from which F is to be determined,
-C             as follows:
-C             = 'D':  Equation (1), discrete-time case;
-C             = 'C':  Equation (2), continuous-time case.
-C
-C     FACT    CHARACTER*1
-C             Specifies how the matrix R is given (factored or not), as
-C             follows:
-C             = 'N':  Array R contains the matrix R;
-C             = 'D':  Array R contains a P-by-M matrix D, where R = D'D;
-C             = 'C':  Array R contains the Cholesky factor of R;
-C             = 'U':  Array R contains the symmetric indefinite UdU' or
-C                     LdL' factorization of R. This option is not
-C                     available for DICO = 'D'.
-C
-C     UPLO    CHARACTER*1
-C             Specifies which triangle of the possibly factored matrix R
-C             (or R + B'XB, on exit) is or should be 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
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A and X.  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             This parameter must be specified only for FACT = 'D'.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,N)
-C             If DICO = 'D', the leading N-by-N part of this array must
-C             contain the state matrix A of the system.
-C             If DICO = 'C', this array is not referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.
-C             LDA >= MAX(1,N) if DICO = 'D';
-C             LDA >= 1        if DICO = 'C'.
-C
-C     B       (input) DOUBLE PRECISION array, dimension (LDB,M)
-C             The leading N-by-M part of this array must contain the
-C             input matrix B of the system.
-C             If DICO = 'D' and FACT = 'D' or 'C', the contents of this
-C             array is destroyed.
-C             Otherwise, B is unchanged on exit.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,M)
-C             On entry, if FACT = 'N', the leading M-by-M upper
-C             triangular part (if UPLO = 'U') or lower triangular part
-C             (if UPLO = 'L') of this array must contain the upper
-C             triangular part or lower triangular part, respectively,
-C             of the symmetric input weighting matrix R.
-C             On entry, if FACT = 'D', the leading P-by-M part of this
-C             array must contain the direct transmission matrix D of the
-C             system.
-C             On entry, if FACT = 'C', the leading M-by-M upper
-C             triangular part (if UPLO = 'U') or lower triangular part
-C             (if UPLO = 'L') of this array must contain the Cholesky
-C             factor of the positive definite input weighting matrix R
-C             (as produced by LAPACK routine DPOTRF).
-C             On entry, if DICO = 'C' and FACT = 'U', the leading M-by-M
-C             upper triangular part (if UPLO = 'U') or lower triangular
-C             part (if UPLO = 'L') of this array must contain the
-C             factors of the UdU' or LdL' factorization, respectively,
-C             of the symmetric indefinite input weighting matrix R (as
-C             produced by LAPACK routine DSYTRF).
-C             The stricly lower triangular part (if UPLO = 'U') or
-C             stricly upper triangular part (if UPLO = 'L') of this
-C             array is used as workspace.
-C             On exit, if OUFACT(1) = 1, and INFO = 0 (or INFO = M+1),
-C             the leading M-by-M upper triangular part (if UPLO = 'U')
-C             or lower triangular part (if UPLO = 'L') of this array
-C             contains the Cholesky factor of the given input weighting
-C             matrix (for DICO = 'C'), or that of the matrix R + B'XB
-C             (for DICO = 'D').
-C             On exit, if OUFACT(1) = 2, and INFO = 0 (or INFO = M+1),
-C             the leading M-by-M upper triangular part (if UPLO = 'U')
-C             or lower triangular part (if UPLO = 'L') of this array
-C             contains the factors of the UdU' or LdL' factorization,
-C             respectively, of the given input weighting matrix
-C             (for DICO = 'C'), or that of the matrix R + B'XB
-C             (for DICO = 'D').
-C             On exit R is unchanged if FACT = 'U'.
-C
-C     LDR     INTEGER.
-C             The leading dimension of the array R.
-C             LDR >= MAX(1,M)   if FACT <> 'D';
-C             LDR >= MAX(1,M,P) if FACT =  'D'.
-C
-C     IPIV    (input/output) INTEGER array, dimension (M)
-C             On entry, if FACT = 'U', this array must contain details
-C             of the interchanges performed and the block structure of
-C             the d factor in the UdU' or LdL' factorization of matrix R
-C             (as produced by LAPACK routine DSYTRF).
-C             On exit, if OUFACT(1) = 2, this array contains details of
-C             the interchanges performed and the block structure of the
-C             d factor in the UdU' or LdL' factorization of matrix R (or
-C             D'D) or R + B'XB (or D'D + B'XB), as produced by LAPACK
-C             routine DSYTRF.
-C             This array is not referenced for DICO = 'D' or FACT = 'D',
-C             or 'C'.
-C
-C     L       (input) DOUBLE PRECISION array, dimension (LDL,M)
-C             If JOBL = 'N', the leading N-by-M part of this array must
-C             contain the cross weighting matrix L.
-C             If JOBL = 'Z', 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'.
-C
-C     X       (input/output) DOUBLE PRECISION array, dimension (LDX,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the solution matrix X of the algebraic Riccati
-C             equation as produced by SLICOT Library routines SB02MD or
-C             SB02OD. Matrix X is assumed non-negative definite.
-C             On exit, if DICO = 'D', FACT = 'D' or 'C', OUFACT(2) = 1,
-C             and INFO = 0, the N-by-N upper triangular part of this
-C             array contains the Cholesky factor of the given matrix X,
-C             which is found to be positive definite.
-C             On exit, if DICO = 'D', FACT = 'D' or 'C', OUFACT(2) = 2,
-C             and INFO = 0, the leading N-by-N part of this array
-C             contains the matrix of orthonormal eigenvectors of X.
-C             On exit X is unchanged if DICO = 'C' or FACT = 'N'.
-C
-C     LDX     INTEGER
-C             The leading dimension of array X.  LDX >= MAX(1,N).
-C
-C     RNORM   (input) DOUBLE PRECISION
-C             If FACT = 'U', this parameter must contain the 1-norm of
-C             the original matrix R (before factoring it).
-C             Otherwise, this parameter is not used.
-C
-C     F       (output) DOUBLE PRECISION array, dimension (LDF,N)
-C             The leading M-by-N part of this array contains the
-C             optimal feedback matrix F.
-C
-C     LDF     INTEGER
-C             The leading dimension of array F.  LDF >= MAX(1,M).
-C
-C     OUFACT  (output) INTEGER array, dimension (2)
-C             Information about the factorization finally used.
-C             OUFACT(1) = 1:  Cholesky factorization of R (or R + B'XB)
-C                             has been used;
-C             OUFACT(1) = 2:  UdU' (if UPLO = 'U') or LdL' (if UPLO =
-C                             'L') factorization of R (or R + B'XB)
-C                             has been used;
-C             OUFACT(2) = 1:  Cholesky factorization of X has been used;
-C             OUFACT(2) = 2:  Spectral factorization of X has been used.
-C             The value of OUFACT(2) is not set for DICO = 'C' or for
-C             DICO = 'D' and FACT = 'N'.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (M)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK, and DWORK(2) contains the reciprocal condition
-C             number of the matrix R (for DICO = 'C') or of R + B'XB
-C             (for DICO = 'D').
-C             If on exit INFO = 0, and OUFACT(2) = 2, then DWORK(3),...,
-C             DWORK(N+2) contain the eigenvalues of X, in ascending
-C             order.
-C
-C     LDWORK  INTEGER
-C             Dimension of working array DWORK.
-C             LDWORK >= max(2,3*M)         if FACT = 'N';
-C             LDWORK >= max(2,2*M)         if FACT = 'U';
-C             LDWORK >= max(2,3*M)         if FACT = 'C', DICO = 'C';
-C             LDWORK >= N+3*M+2            if FACT = 'C', DICO = 'D';
-C             LDWORK >= max(2,min(P,M)+M)  if FACT = 'D', DICO = 'C';
-C             LDWORK >= max(N+3*M+2,4*N+1) if FACT = 'D', DICO = 'D'.
-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             = i:  if the i-th element of the d factor is exactly zero;
-C                   the UdU' (or LdL') factorization has been completed,
-C                   but the block diagonal matrix d is exactly singular;
-C             = M+1:  if the matrix R (if DICO = 'C'), or R + B'XB
-C                   (if DICO = 'D') is numerically singular (to working
-C                   precision);
-C             = M+2:  if one or more of the eigenvalues of X has not
-C                   converged.
-C
-C     METHOD
-C
-C     The optimal feedback matrix F is obtained as the solution to the
-C     system of linear equations
-C
-C        (R + B'XB) * F = B'XA + L'
-C
-C     in the discrete-time case and
-C
-C        R * F = B'X + L'
-C
-C     in the continuous-time case, with R replaced by D'D if FACT = 'D'.
-C     The factored form of R, specified by FACT <> 'N', is taken into
-C     account. If FACT = 'N', Cholesky factorization is tried first, but
-C     if the coefficient matrix is not positive definite, then UdU' (or
-C     LdL') factorization is used. The discrete-time case involves
-C     updating of a triangular factorization of R (or D'D); Cholesky or
-C     symmetric spectral factorization of X is employed to avoid
-C     squaring of the condition number of the matrix. When D is given,
-C     its QR factorization is determined, and the triangular factor is
-C     used as described above.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm consists of numerically stable steps.
-C                                    3     2
-C     For DICO = 'C', it requires O(m  + mn ) floating point operations
-C                           2
-C     if FACT = 'N' and O(mn ) floating point operations, otherwise.
-C     For DICO = 'D', the operation counts are similar, but additional
-C        3
-C     O(n ) floating point operations may be needed in the worst case.
-C
-C     CONTRIBUTORS
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Sep. 1997.
-C     Supersedes Release 2.0 routine SB02BD by M. Vanbegin, and
-C     P. Van Dooren, Philips Research Laboratory, Brussels, Belgium.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Algebraic Riccati equation, closed loop system, continuous-time
-C     system, discrete-time system, matrix algebra, optimal control,
-C     optimal regulator.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, FACT, JOBL, UPLO
-      INTEGER           INFO, LDA, LDB, LDF, LDL, LDR, LDWORK, LDX, M,
-     $                  N, P
-      DOUBLE PRECISION  RNORM
-C     .. Array Arguments ..
-      INTEGER           IPIV(*), IWORK(*), OUFACT(2)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), DWORK(*), F(LDF,*),
-     $                  L(LDL,*), R(LDR,*), X(LDX,*)
-C     .. Local Scalars ..
-      LOGICAL           DISCR, LFACTA, LFACTC, LFACTD, LFACTU, LUPLOU,
-     $                  WITHL
-      INTEGER           I, IFAIL, ITAU, J, JW, JWORK, JZ, WRKOPT
-      DOUBLE PRECISION  EPS, RCOND, RNORMP, TEMP
-C     .. Local Arrays ..
-      DOUBLE PRECISION  DUMMY(1)
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH, DLANSY
-      EXTERNAL          DLAMCH, DLANSY, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DCOPY, DGEMM, DGEMV, DGEQRF, DLASET, DPOCON,
-     $                  DPOTRF, DPOTRS, DSCAL, DSYCON, DSYEV, DSYTRF,
-     $                  DSYTRS, DTRCON, DTRMM, MB04KD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         ABS, INT, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      INFO = 0
-      DISCR  = LSAME( DICO, 'D' )
-      LFACTC = LSAME( FACT, 'C' )
-      LFACTD = LSAME( FACT, 'D' )
-      LFACTU = LSAME( FACT, 'U' )
-      LUPLOU = LSAME( UPLO, 'U' )
-      WITHL  = LSAME( JOBL, 'N' )
-      LFACTA = LFACTC.OR.LFACTD.OR.LFACTU
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.DISCR .AND. .NOT.LSAME( DICO, 'C' ) ) THEN
-         INFO = -1
-      ELSE IF( ( .NOT.LFACTA .AND. .NOT.LSAME( FACT, 'N' ) ) .OR.
-     $         ( DISCR .AND. LFACTU ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.LUPLOU .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT.WITHL .AND. .NOT.LSAME( JOBL, 'Z' ) ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( ( .NOT.DISCR .AND. LDA.LT.1 )             .OR.
-     $         (      DISCR .AND. LDA.LT.MAX( 1, N ) ) ) THEN
-         INFO = -9
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( (              LDR.LT.MAX( 1, M ) )   .OR.
-     $         ( LFACTD .AND. LDR.LT.MAX( 1, P ) ) ) THEN
-         INFO = -13
-      ELSE IF( ( .NOT.WITHL .AND. LDL.LT.1 )             .OR.
-     $         (      WITHL .AND. LDL.LT.MAX( 1, N ) ) ) THEN
-         INFO = -16
-      ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
-         INFO = -18
-      ELSE IF( LFACTU ) THEN
-         IF( RNORM.LT.ZERO )
-     $      INFO = -19
-      END IF
-      IF( LDF.LT.MAX( 1, M ) ) THEN
-         INFO = -21
-      ELSE IF( ( ( .NOT.LFACTA .OR. ( LFACTC .AND. .NOT.DISCR ) )
-     $                         .AND. LDWORK.LT.MAX( 2, 3*M ) ) .OR.
-     $         (        LFACTU .AND. LDWORK.LT.MAX( 2, 2*M ) ) .OR.
-     $    ( DISCR .AND. LFACTC .AND. LDWORK.LT.N + 3*M + 2 )   .OR.
-     $(.NOT.DISCR .AND. LFACTD .AND. LDWORK.LT.MAX( 2, MIN(P,M) + M ) )
-     $                                                         .OR.
-     $    ( DISCR .AND. LFACTD .AND. LDWORK.LT.MAX( N + 3*M + 2,
-     $                                              4*N + 1 ) ) ) THEN
-         INFO = -25
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB02ND', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( N.EQ.0 .OR. M.EQ.0 .OR. ( LFACTD .AND. P.EQ.0 ) ) THEN
-        DWORK(1) = ONE
-        DWORK(2) = ONE
-        RETURN
-      END IF
-C
-      WRKOPT = 1
-      EPS = DLAMCH( 'Epsilon' )
-C
-C     Determine the right-hand side of the matrix equation.
-C     Compute  B'X  in F.
-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
-      CALL DGEMM( 'Transpose', 'No transpose', M, N, N, ONE, B, LDB, X,
-     $            LDX, ZERO, F, LDF )
-C
-      IF ( .NOT.LFACTA ) THEN
-         IF ( DISCR ) THEN
-C
-C           Discrete-time case with R not factored. Compute R + B'XB.
-C
-            IF ( LUPLOU ) THEN
-C
-               DO 10 J = 1, M
-                  CALL DGEMV( 'No transpose', J, N, ONE, F, LDF, B(1,J),
-     $                        1, ONE, R(1,J), 1 )
-   10          CONTINUE
-C
-            ELSE
-C
-               DO 20 J = 1, M
-                  CALL DGEMV( 'Transpose', N, J, ONE, B, LDB, F(J,1),
-     $                        LDF, ONE, R(J,1), LDR )
-   20          CONTINUE
-C
-            END IF
-         END IF
-C
-C        Compute the 1-norm of the matrix  R  or  R + B'XB.
-C        Workspace: need M.
-C
-         RNORMP = DLANSY( '1-norm', UPLO, M, R, LDR, DWORK )
-         WRKOPT = MAX( WRKOPT, M )
-      END IF
-C
-      IF ( DISCR ) THEN
-C
-C        For discrete-time case, postmultiply B'X by A.
-C        Workspace: need N.
-C
-         DO 30 I = 1, M
-            CALL DCOPY( N, F(I,1), LDF, DWORK, 1 )
-            CALL DGEMV( 'Transpose', N, N, ONE, A, LDA, DWORK, 1, ZERO,
-     $                  F(I,1), LDF )
-   30    CONTINUE
-C
-         WRKOPT = MAX( WRKOPT, N )
-      END IF
-C
-      IF( WITHL ) THEN
-C
-C        Add L'.
-C
-         DO 50 I = 1, M
-C
-            DO 40 J = 1, N
-               F(I,J) = F(I,J) + L(J,I)
-   40       CONTINUE
-C
-   50    CONTINUE
-C
-      END IF
-C
-C     Solve the matrix equation.
-C
-      IF ( LFACTA ) THEN
-C
-C        Case 1: Matrix R is given in a factored form.
-C
-         IF ( LFACTD ) THEN
-C
-C           Use QR factorization of D.
-C           Workspace: need   min(P,M) + M,
-C                      prefer min(P,M) + M*NB.
-C
-            ITAU = 1
-            JWORK = ITAU + MIN( P, M )
-            CALL DGEQRF( P, M, R, LDR, DWORK(ITAU), DWORK(JWORK),
-     $                   LDWORK-JWORK+1, IFAIL )
-            WRKOPT = MAX( WRKOPT, INT( DWORK(JWORK) )+JWORK-1 )
-C
-C           Make positive the diagonal elements of the triangular
-C           factor. Construct the strictly lower triangle, if requested.
-C
-            DO 70 I = 1, M
-               IF ( R(I,I).LT.ZERO ) THEN
-C
-                  DO 60 J = I, M
-                     R(I,J) = -R(I,J)
-   60             CONTINUE
-C
-               END IF
-               IF ( .NOT.LUPLOU )
-     $            CALL DCOPY( I-1, R(1,I), 1, R(I,1), LDR )
-   70       CONTINUE
-C
-            IF ( P.LT.M ) THEN
-               CALL DLASET( 'Full', M-P, M, ZERO, ZERO, R(P+1,1), LDR )
-               IF ( .NOT.DISCR ) THEN
-                  DWORK(2) = ZERO
-                  INFO = M + 1
-                  RETURN
-               END IF
-            END IF
-         END IF
-C
-         JW = 1
-         IF ( DISCR ) THEN
-C
-C           Discrete-time case. Update the factorization for B'XB.
-C           Try first the Cholesky factorization of X, saving the
-C           diagonal of X, in order to recover it, if X is not positive
-C           definite. In the later case, use spectral factorization.
-C           Workspace: need N.
-C           Define     JW = 1   for Cholesky factorization of X,
-C                      JW = N+3 for spectral factorization of X.
-C
-            CALL DCOPY( N, X, LDX+1, DWORK, 1 )
-            CALL DPOTRF( 'Upper', N, X, LDX, IFAIL )
-            IF ( IFAIL.EQ.0 ) THEN
-C
-C              Use Cholesky factorization of X to compute chol(X)*B.
-C
-               OUFACT(2) = 1
-               CALL DTRMM( 'Left', 'Upper', 'No transpose', 'Non unit',
-     $                     N, M, ONE, X, LDX, B, LDB )
-            ELSE
-C
-C              Use spectral factorization of X, X = UVU'.
-C              Workspace: need   4*N+1,
-C                         prefer N*(NB+2)+N+2.
-C
-               JW = N + 3
-               OUFACT(2) = 2
-               CALL DCOPY( N, DWORK, 1, X, LDX+1 )
-               CALL DSYEV( 'Vectors', 'Lower', N, X, LDX, DWORK(3),
-     $                     DWORK(JW), LDWORK-JW+1, IFAIL )
-               IF ( IFAIL.GT.0 ) THEN
-                  INFO = M + 2
-                  RETURN
-               END IF
-               WRKOPT = MAX( WRKOPT, INT( DWORK(JW) )+JW-1 )
-               TEMP = ABS( DWORK(N+2) )*EPS
-C
-C              Count the negligible eigenvalues and compute sqrt(V)U'B.
-C              Workspace: need 2*N+2.
-C
-               JZ = 0
-C
-   80          CONTINUE
-               IF ( ABS( DWORK(JZ+3) ).LE.TEMP ) THEN
-                  JZ = JZ + 1
-                  IF ( JZ.LT.N) GO TO 80
-               END IF
-C
-               DO 90 J = 1, M
-                  CALL DCOPY( N, B(1,J), 1, DWORK(JW), 1 )
-                  CALL DGEMV( 'Transpose', N, N, ONE, X, LDX, DWORK(JW),
-     $                        1, ZERO, B(1,J), 1 )
-   90          CONTINUE
-C
-               DO 100 I = JZ + 1, N
-                  CALL DSCAL( M, SQRT( ABS( DWORK(I+2) ) ), B(I,1), LDB
-     $                      )
-  100          CONTINUE
-C
-               IF ( JZ.GT.0 )
-     $            CALL DLASET( 'Full', JZ, M, ZERO, ZERO, B, LDB )
-            END IF
-C
-C           Update the triangular factorization.
-C
-            IF ( .NOT.LUPLOU ) THEN
-C
-C              For efficiency, use the transposed of the lower triangle.
-C
-               DO 110 I = 2, M
-                  CALL DCOPY( I-1, R(I,1), LDR, R(1,I), 1 )
-  110          CONTINUE
-C
-            END IF
-C
-C           Workspace: need JW+2*M-1.
-C
-            CALL MB04KD( 'Full', M, 0, N, R, LDR, B, LDB, DUMMY, N,
-     $                   DUMMY, M, DWORK(JW), DWORK(JW+N) )
-            WRKOPT = MAX( WRKOPT, JW + 2*M - 1 )
-C
-C           Make positive the diagonal elements of the triangular
-C           factor.
-C
-            DO 130 I = 1, M
-               IF ( R(I,I).LT.ZERO ) THEN
-C
-                  DO 120 J = I, M
-                     R(I,J) = -R(I,J)
-  120             CONTINUE
-C
-               END IF
-  130       CONTINUE
-C
-            IF ( .NOT.LUPLOU ) THEN
-C
-C              Construct the lower triangle.
-C
-               DO 140 I = 2, M
-                  CALL DCOPY( I-1, R(1,I), 1, R(I,1), LDR )
-  140          CONTINUE
-C
-            END IF
-         END IF
-C
-C        Compute the condition number of the coefficient matrix.
-C
-         IF ( .NOT.LFACTU ) THEN
-C
-C           Workspace: need JW+3*M-1.
-C
-            CALL DTRCON( '1-norm', UPLO, 'Non unit', M, R, LDR, RCOND,
-     $                    DWORK(JW), IWORK, IFAIL )
-            OUFACT(1) = 1
-            WRKOPT = MAX( WRKOPT, JW + 3*M - 1 )
-         ELSE
-C
-C           Workspace: need 2*M.
-C
-            CALL DSYCON( UPLO, M, R, LDR, IPIV, RNORM, RCOND, DWORK,
-     $                   IWORK, INFO )
-            OUFACT(1) = 2
-            WRKOPT = MAX( WRKOPT, 2*M )
-         END IF
-         DWORK(2) = RCOND
-         IF( RCOND.LT.EPS ) THEN
-            INFO = M + 1
-            RETURN
-         END IF
-C
-      ELSE
-C
-C        Case 2: Matrix R is given in an unfactored form.
-C
-C        Save the given triangle of  R  or  R + B'XB  in the other
-C        strict triangle and the diagonal in the workspace, and try
-C        Cholesky factorization.
-C        Workspace: need M.
-C
-         CALL DCOPY( M, R, LDR+1, DWORK, 1 )
-         IF( LUPLOU ) THEN
-C
-            DO 150 J = 2, M
-               CALL DCOPY( J-1, R(1,J), 1, R(J,1), LDR )
-  150       CONTINUE
-C
-         ELSE
-C
-            DO 160 J = 2, M
-               CALL DCOPY( J-1, R(J,1), LDR, R(1,J), 1 )
-  160       CONTINUE
-C
-         END IF
-         CALL DPOTRF( UPLO, M, R, LDR, INFO )
-         OUFACT(1) = 1
-         IF( INFO.EQ.0 ) THEN
-C
-C           Compute the reciprocal of the condition number of R.
-C           Workspace: need 3*M.
-C
-            CALL DPOCON( UPLO, M, R, LDR, RNORMP, RCOND, DWORK, IWORK,
-     $                   INFO )
-C
-C           Return if the matrix is singular to working precision.
-C
-            DWORK(2) = RCOND
-            IF( RCOND.LT.EPS ) THEN
-               INFO = M + 1
-               RETURN
-            END IF
-            WRKOPT = MAX( WRKOPT, 3*M )
-         ELSE
-C
-C           Use UdU' or LdL' factorization, first restoring the saved
-C           triangle.
-C
-            CALL DCOPY( M, DWORK, 1, R, LDR+1 )
-            IF( LUPLOU ) THEN
-C
-               DO 170 J = 2, M
-                  CALL DCOPY( J-1, R(J,1), LDR, R(1,J), 1 )
-  170          CONTINUE
-C
-            ELSE
-C
-               DO 180 J = 2, M
-                  CALL DCOPY( J-1, R(1,J), 1, R(J,1), LDR )
-  180          CONTINUE
-C
-            END IF
-C
-C           Workspace: need   1,
-C                      prefer M*NB.
-C
-            CALL DSYTRF( UPLO, M, R, LDR, IPIV, DWORK, LDWORK, INFO )
-            OUFACT(1) = 2
-            IF( INFO.GT.0 )
-     $         RETURN
-            WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) )
-C
-C           Compute the reciprocal of the condition number of R.
-C           Workspace: need   2*M.
-C
-            CALL DSYCON( UPLO, M, R, LDR, IPIV, RNORMP, RCOND, DWORK,
-     $                   IWORK, INFO )
-C
-C           Return if the matrix is singular to working precision.
-C
-            DWORK(2) = RCOND
-            IF( RCOND.LT.EPS ) THEN
-               INFO = M + 1
-               RETURN
-            END IF
-         END IF
-      END IF
-C
-      IF (OUFACT(1).EQ.1 ) THEN
-C
-C        Solve the positive definite linear system.
-C
-         CALL DPOTRS( UPLO, M, N, R, LDR, F, LDF, INFO )
-      ELSE
-C
-C        Solve the indefinite linear system.
-C
-         CALL DSYTRS( UPLO, M, N, R, LDR, IPIV, F, LDF, INFO )
-      END IF
-C
-C     Set the optimal workspace.
-C
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of SB02ND ***
-      END
--- a/extra/control-devel/src/SB02QD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,804 +0,0 @@
-      SUBROUTINE SB02QD( JOB, FACT, TRANA, UPLO, LYAPUN, N, A, LDA, T,
-     $                   LDT, U, LDU, G, LDG, Q, LDQ, X, LDX, SEP,
-     $                   RCOND, FERR, 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 estimate the conditioning and compute an error bound on the
-C     solution of the real continuous-time matrix algebraic Riccati
-C     equation
-C
-C         op(A)'*X + X*op(A) + Q - X*G*X = 0,                        (1)
-C
-C     where op(A) = A or A' (A**T) and Q, G are symmetric (Q = Q**T,
-C     G = G**T). The matrices A, Q and G are N-by-N and the solution X
-C     is N-by-N.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies the computation to be performed, as follows:
-C             = 'C':  Compute the reciprocal condition number only;
-C             = 'E':  Compute the error bound only;
-C             = 'B':  Compute both the reciprocal condition number and
-C                     the error bound.
-C
-C     FACT    CHARACTER*1
-C             Specifies whether or not the real Schur factorization of
-C             the matrix Ac = A - G*X (if TRANA = 'N') or Ac = A - X*G
-C             (if TRANA = 'T' or 'C') is supplied on entry, as follows:
-C             = 'F':  On entry, T and U (if LYAPUN = 'O') contain the
-C                     factors from the real Schur factorization of the
-C                     matrix Ac;
-C             = 'N':  The Schur factorization of Ac will be computed
-C                     and the factors will be stored in T and U (if
-C                     LYAPUN = 'O').
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     UPLO    CHARACTER*1
-C             Specifies which part of the symmetric matrices Q and G is
-C             to be used, as follows:
-C             = 'U':  Upper triangular part;
-C             = 'L':  Lower triangular part.
-C
-C     LYAPUN  CHARACTER*1
-C             Specifies whether or not the original Lyapunov equations
-C             should be solved in the iterative estimation process,
-C             as follows:
-C             = 'O':  Solve the original Lyapunov equations, updating
-C                     the right-hand sides and solutions with the
-C                     matrix U, e.g., RHS <-- U'*RHS*U;
-C             = 'R':  Solve reduced Lyapunov equations only, without
-C                     updating the right-hand sides and solutions.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A, X, Q, and G.  N >= 0.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,N)
-C             If FACT = 'N' or LYAPUN = 'O', the leading N-by-N part of
-C             this array must contain the matrix A.
-C             If FACT = 'F' and LYAPUN = 'R', A is not referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.
-C             LDA >= max(1,N), if FACT = 'N' or  LYAPUN = 'O';
-C             LDA >= 1,        if FACT = 'F' and LYAPUN = 'R'.
-C
-C     T       (input or output) DOUBLE PRECISION array, dimension
-C             (LDT,N)
-C             If FACT = 'F', then T is an input argument and on entry,
-C             the leading N-by-N upper Hessenberg part of this array
-C             must contain the upper quasi-triangular matrix T in Schur
-C             canonical form from a Schur factorization of Ac (see
-C             argument FACT).
-C             If FACT = 'N', then T is an output argument and on exit,
-C             if INFO = 0 or INFO = N+1, the leading N-by-N upper
-C             Hessenberg part of this array contains the upper quasi-
-C             triangular matrix T in Schur canonical form from a Schur
-C             factorization of Ac (see argument FACT).
-C
-C     LDT     INTEGER
-C             The leading dimension of the array T.  LDT >= max(1,N).
-C
-C     U       (input or output) DOUBLE PRECISION array, dimension
-C             (LDU,N)
-C             If LYAPUN = 'O' and FACT = 'F', then U is an input
-C             argument and on entry, the leading N-by-N part of this
-C             array must contain the orthogonal matrix U from a real
-C             Schur factorization of Ac (see argument FACT).
-C             If LYAPUN = 'O' and FACT = 'N', then U is an output
-C             argument and on exit, if INFO = 0 or INFO = N+1, it
-C             contains the orthogonal N-by-N matrix from a real Schur
-C             factorization of Ac (see argument FACT).
-C             If LYAPUN = 'R', the array U is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of the array U.
-C             LDU >= 1,        if LYAPUN = 'R';
-C             LDU >= MAX(1,N), if LYAPUN = 'O'.
-C
-C     G       (input) DOUBLE PRECISION array, dimension (LDG,N)
-C             If UPLO = 'U', the leading N-by-N upper triangular part of
-C             this array must contain the upper triangular part of the
-C             matrix G.
-C             If UPLO = 'L', the leading N-by-N lower triangular part of
-C             this array must contain the lower triangular part of the
-C             matrix G.                     _
-C             Matrix G should correspond to G in the "reduced" Riccati
-C             equation (with matrix T, instead of A), if LYAPUN = 'R'.
-C             See METHOD.
-C
-C     LDG     INTEGER
-C             The leading dimension of the array G.  LDG >= max(1,N).
-C
-C     Q       (input) DOUBLE PRECISION array, dimension (LDQ,N)
-C             If UPLO = 'U', the leading N-by-N upper triangular part of
-C             this array must contain the upper triangular part of the
-C             matrix Q.
-C             If UPLO = 'L', the leading N-by-N lower triangular part of
-C             this array must contain the lower triangular part of the
-C             matrix Q.                     _
-C             Matrix Q should correspond to Q in the "reduced" Riccati
-C             equation (with matrix T, instead of A), if LYAPUN = 'R'.
-C             See METHOD.
-C
-C     LDQ     INTEGER
-C             The leading dimension of the array Q.  LDQ >= max(1,N).
-C
-C     X       (input) DOUBLE PRECISION array, dimension (LDX,N)
-C             The leading N-by-N part of this array must contain the
-C             symmetric solution matrix of the original Riccati
-C             equation (with matrix A), if LYAPUN = 'O', or of the
-C             "reduced" Riccati equation (with matrix T), if
-C             LYAPUN = 'R'. See METHOD.
-C
-C     LDX     INTEGER
-C             The leading dimension of the array X.  LDX >= max(1,N).
-C
-C     SEP     (output) DOUBLE PRECISION
-C             If JOB = 'C' or JOB = 'B', the estimated quantity
-C             sep(op(Ac),-op(Ac)').
-C             If N = 0, or X = 0, or JOB = 'E', SEP is not referenced.
-C
-C     RCOND   (output) DOUBLE PRECISION
-C             If JOB = 'C' or JOB = 'B', an estimate of the reciprocal
-C             condition number of the continuous-time Riccati equation.
-C             If N = 0 or X = 0, RCOND is set to 1 or 0, respectively.
-C             If JOB = 'E', RCOND is not referenced.
-C
-C     FERR    (output) DOUBLE PRECISION
-C             If JOB = 'E' or JOB = 'B', an estimated forward error
-C             bound for the solution X. If XTRUE is the true solution,
-C             FERR bounds the magnitude of the largest entry in
-C             (X - XTRUE) divided by the magnitude of the largest entry
-C             in X.
-C             If N = 0 or X = 0, FERR is set to 0.
-C             If JOB = 'C', FERR is not referenced.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N*N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0 or INFO = N+1, DWORK(1) returns the
-C             optimal value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The dimension of the array DWORK.
-C             Let LWA = N*N, if LYAPUN = 'O' and JOB = 'E' or 'B';
-C                 LWA = 0,   otherwise.
-C             If FACT = 'N', then
-C                LDWORK  = MAX(1, 5*N, 2*N*N),        if JOB = 'C';
-C                LDWORK  = MAX(1, LWA + 5*N, 4*N*N ), if JOB = 'E', 'B'.
-C             If FACT = 'F', then
-C                LDWORK  = MAX(1, 2*N*N),  if JOB = 'C';
-C                LDWORK  = MAX(1, 4*N*N ), if JOB = 'E' or 'B'.
-C             For good performance, LDWORK must generally 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             > 0:  if INFO = i, i <= N, the QR algorithm failed to
-C                   complete the reduction of the matrix Ac to Schur
-C                   canonical form (see LAPACK Library routine DGEES);
-C                   on exit, the matrix T(i+1:N,i+1:N) contains the
-C                   partially converged Schur form, and DWORK(i+1:N) and
-C                   DWORK(N+i+1:2*N) contain the real and imaginary
-C                   parts, respectively, of the converged eigenvalues;
-C                   this error is unlikely to appear;
-C             = N+1:  if the matrices T and -T' have common or very
-C                   close eigenvalues; perturbed values were used to
-C                   solve Lyapunov equations, but the matrix T, if given
-C                   (for FACT = 'F'), is unchanged.
-C
-C     METHOD
-C
-C     The condition number of the Riccati equation is estimated as
-C
-C     cond = ( norm(Theta)*norm(A) + norm(inv(Omega))*norm(Q) +
-C                 norm(Pi)*norm(G) ) / norm(X),
-C
-C     where Omega, Theta and Pi are linear operators defined by
-C
-C     Omega(W) = op(Ac)'*W + W*op(Ac),
-C     Theta(W) = inv(Omega(op(W)'*X + X*op(W))),
-C        Pi(W) = inv(Omega(X*W*X)),
-C
-C     and Ac = A - G*X (if TRANA = 'N') or Ac = A - X*G (if TRANA = 'T'
-C     or 'C'). Note that the Riccati equation (1) is equivalent to
-C                _   _         _   _ _ _
-C         op(T)'*X + X*op(T) + Q + X*G*X = 0,                        (2)
-C           _           _               _
-C     where X = U'*X*U, Q = U'*Q*U, and G = U'*G*U, with U the
-C     orthogonal matrix reducing Ac to a real Schur form, T = U'*Ac*U.
-C
-C     The routine estimates the quantities
-C
-C     sep(op(Ac),-op(Ac)') = 1 / norm(inv(Omega)),
-C
-C     norm(Theta) and norm(Pi) using 1-norm condition estimator.
-C
-C     The forward error bound is estimated using a practical error bound
-C     similar to the one proposed in [2].
-C
-C     REFERENCES
-C
-C     [1] Ghavimi, A.R. and Laub, A.J.
-C         Backward error, sensitivity, and refinement of computed
-C         solutions of algebraic Riccati equations.
-C         Numerical Linear Algebra with Applications, vol. 2, pp. 29-49,
-C         1995.
-C
-C     [2] Higham, N.J.
-C         Perturbation theory and backward error for AX-XB=C.
-C         BIT, vol. 33, pp. 124-136, 1993.
-C
-C     [3] Petkov, P.Hr., Konstantinov, M.M., and Mehrmann, V.
-C         DGRSVX and DMSRIC: Fortran 77 subroutines for solving
-C         continuous-time matrix algebraic Riccati equations with
-C         condition and accuracy estimates.
-C         Preprint SFB393/98-16, Fak. f. Mathematik, Tech. Univ.
-C         Chemnitz, May 1998.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations.
-C     The accuracy of the estimates obtained depends on the solution
-C     accuracy and on the properties of the 1-norm estimator.
-C
-C     FURTHER COMMENTS
-C
-C     The option LYAPUN = 'R' may occasionally produce slightly worse
-C     or better estimates, and it is much faster than the option 'O'.
-C     When SEP is computed and it is zero, the routine returns
-C     immediately, with RCOND and FERR (if requested) set to 0 and 1,
-C     respectively. In this case, the equation is singular.
-C
-C     CONTRIBUTOR
-C
-C     P.Hr. Petkov, Technical University of Sofia, December 1998.
-C     V. Sima, Katholieke Univ. Leuven, Belgium, February 1999.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2004.
-C
-C     KEYWORDS
-C
-C     Conditioning, error estimates, orthogonal transformation,
-C     real Schur form, Riccati equation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, FOUR, HALF
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
-     $                     FOUR = 4.0D+0, HALF = 0.5D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          FACT, JOB, LYAPUN, TRANA, UPLO
-      INTEGER            INFO, LDA, LDG, LDQ, LDT, LDU, LDWORK, LDX, N
-      DOUBLE PRECISION   FERR, RCOND, SEP
-C     ..
-C     .. Array Arguments ..
-      INTEGER            IWORK( * )
-      DOUBLE PRECISION   A( LDA, * ), DWORK( * ),  G( LDG, * ),
-     $                   Q( LDQ, * ), T( LDT, * ), U( LDU, * ),
-     $                   X( LDX, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            JOBB, JOBC, JOBE, LOWER, NEEDAC, NOFACT,
-     $                   NOTRNA, UPDATE
-      CHARACTER          LOUP, SJOB, TRANAT
-      INTEGER            I, IABS, INFO2, IRES, ITMP, IXBS, J, JJ, JX,
-     $                   KASE, LDW, LWA, NN, SDIM, WRKOPT
-      DOUBLE PRECISION   ANORM, BIGNUM, DENOM, EPS, EPSN, EST, GNORM,
-     $                   PINORM, QNORM, SCALE, SIG, TEMP, THNORM, TMAX,
-     $                   XANORM, XNORM
-C     ..
-C     .. Local Arrays ..
-      LOGICAL            BWORK( 1 )
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME, SELECT
-      DOUBLE PRECISION   DLAMCH, DLANGE, DLANHS, DLANSY
-      EXTERNAL           DLAMCH, DLANGE, DLANHS, DLANSY, LSAME, SELECT
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DAXPY, DCOPY, DGEES, DLACON, DLACPY, DSCAL,
-     $                   DSYMM, DSYR2K, MA02ED, MB01RU, MB01UD, SB03MY,
-     $                   SB03QX, SB03QY, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, DBLE, INT, MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode and Test input parameters.
-C
-      JOBC   = LSAME( JOB,    'C' )
-      JOBE   = LSAME( JOB,    'E' )
-      JOBB   = LSAME( JOB,    'B' )
-      NOFACT = LSAME( FACT,   'N' )
-      NOTRNA = LSAME( TRANA,  'N' )
-      LOWER  = LSAME( UPLO,   'L' )
-      UPDATE = LSAME( LYAPUN, 'O' )
-C
-      NEEDAC = UPDATE .AND. .NOT.JOBC
-C
-      NN = N*N
-      IF( NEEDAC ) THEN
-         LWA = NN
-      ELSE
-         LWA = 0
-      END IF
-C
-      IF( NOFACT ) THEN
-         IF( JOBC ) THEN
-            LDW = MAX( 5*N, 2*NN )
-         ELSE
-            LDW = MAX( LWA + 5*N, 4*NN )
-         END IF
-      ELSE
-         IF( JOBC ) THEN
-            LDW = 2*NN
-         ELSE
-            LDW = 4*NN
-         END IF
-      END IF
-C
-      INFO = 0
-      IF( .NOT.( JOBB .OR. JOBC .OR. JOBE ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( NOFACT .OR. LSAME( FACT,   'F' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.( NOTRNA .OR. LSAME( TRANA,  'T' ) .OR.
-     $                            LSAME( TRANA,  'C' ) ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT.( LOWER  .OR. LSAME( UPLO,   'U' ) ) ) THEN
-         INFO = -4
-      ELSE IF( .NOT.( UPDATE .OR. LSAME( LYAPUN, 'R' ) ) ) THEN
-         INFO = -5
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( LDA.LT.1 .OR.
-     $       ( LDA.LT.N .AND. ( UPDATE .OR. NOFACT ) ) ) THEN
-         INFO = -8
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -10
-      ELSE IF( LDU.LT.1 .OR. ( LDU.LT.N .AND. UPDATE ) ) THEN
-         INFO = -12
-      ELSE IF( LDG.LT.MAX( 1, N ) ) THEN
-         INFO = -14
-      ELSE IF( LDQ.LT.MAX( 1, N ) ) THEN
-         INFO = -16
-      ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
-         INFO = -18
-      ELSE IF( LDWORK.LT.MAX( 1, LDW ) ) THEN
-         INFO = -24
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'SB02QD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( N.EQ.0 ) THEN
-         IF( .NOT.JOBE )
-     $      RCOND = ONE
-         IF( .NOT.JOBC )
-     $      FERR  = ZERO
-         DWORK( 1 ) = ONE
-         RETURN
-      END IF
-C
-C     Compute the 1-norm of the matrix X.
-C
-      XNORM = DLANSY( '1-norm', UPLO, N, X, LDX, DWORK )
-      IF( XNORM.EQ.ZERO ) THEN
-C
-C        The solution is zero.
-C
-         IF( .NOT.JOBE )
-     $      RCOND = ZERO
-         IF( .NOT.JOBC )
-     $      FERR  = ZERO
-         DWORK( 1 ) = DBLE( N )
-         RETURN
-      END IF
-C
-C     Workspace usage.
-C
-      IXBS = 0
-      ITMP = IXBS + NN
-      IABS = ITMP + NN
-      IRES = IABS + NN
-C
-C     Workspace:  LWR, where
-C                 LWR = N*N, if LYAPUN = 'O' and JOB = 'E' or 'B', or
-C                               FACT = 'N',
-C                 LWR = 0,   otherwise.
-C
-      IF( NEEDAC .OR. NOFACT ) THEN
-C
-         CALL DLACPY( 'Full', N, N, A, LDA, DWORK, N )
-         IF( NOTRNA ) THEN
-C
-C           Compute Ac = A - G*X.
-C
-            CALL DSYMM( 'Left', UPLO, N, N, -ONE, G, LDG, X, LDX, ONE,
-     $                  DWORK, N )
-         ELSE
-C
-C           Compute Ac = A - X*G.
-C
-            CALL DSYMM( 'Right', UPLO, N, N, -ONE, G, LDG, X, LDX, ONE,
-     $                  DWORK, N )
-         END IF
-C
-         WRKOPT = DBLE( NN )
-         IF( NOFACT )
-     $      CALL DLACPY( 'Full', N, N, DWORK, N, T, LDT )
-      ELSE
-         WRKOPT = DBLE( N )
-      END IF
-C
-      IF( NOFACT ) THEN
-C
-C        Compute the Schur factorization of Ac, Ac = U*T*U'.
-C        Workspace:  need   LWA + 5*N;
-C                    prefer larger;
-C                    LWA = N*N, if LYAPUN = 'O' and JOB = 'E' or 'B';
-C                    LWA = 0,   otherwise.
-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
-         IF( UPDATE ) THEN
-            SJOB = 'V'
-         ELSE
-            SJOB = 'N'
-         END IF
-         CALL DGEES( SJOB, 'Not ordered', SELECT, N, T, LDT, SDIM,
-     $               DWORK( LWA+1 ), DWORK( LWA+N+1 ), U, LDU,
-     $               DWORK( LWA+2*N+1 ), LDWORK-LWA-2*N, BWORK, INFO )
-         IF( INFO.GT.0 ) THEN
-            IF( LWA.GT.0 )
-     $         CALL DCOPY( 2*N, DWORK( LWA+1 ), 1, DWORK, 1 )
-            RETURN
-         END IF
-C
-         WRKOPT = MAX( WRKOPT, INT( DWORK( LWA+2*N+1 ) ) + LWA + 2*N )
-      END IF
-      IF( NEEDAC )
-     $   CALL DLACPY( 'Full', N, N, DWORK, N, DWORK( IABS+1 ), N )
-C
-      IF( NOTRNA ) THEN
-         TRANAT = 'T'
-      ELSE
-         TRANAT = 'N'
-      END IF
-C
-      IF( .NOT.JOBE ) THEN
-C
-C        Estimate sep(op(Ac),-op(Ac)') = sep(op(T),-op(T)') and
-C        norm(Theta).
-C        Workspace LWA + 2*N*N.
-C
-         CALL SB03QY( 'Both', TRANA, LYAPUN, N, T, LDT, U, LDU, X, LDX,
-     $                SEP, THNORM, IWORK, DWORK, LDWORK, INFO )
-C
-         WRKOPT = MAX( WRKOPT, LWA + 2*NN )
-C
-C        Return if the equation is singular.
-C
-         IF( SEP.EQ.ZERO ) THEN
-            RCOND = ZERO
-            IF( JOBB )
-     $         FERR = ONE
-            DWORK( 1 ) = DBLE( WRKOPT )
-            RETURN
-         END IF
-C
-C        Estimate norm(Pi).
-C        Workspace LWA + 2*N*N.
-C
-         KASE = 0
-C
-C        REPEAT
-   10    CONTINUE
-         CALL DLACON( NN, DWORK( ITMP+1 ), DWORK, IWORK, EST, KASE )
-         IF( KASE.NE.0 ) THEN
-C
-C           Select the triangular part of symmetric matrix to be used.
-C
-            IF( DLANSY( '1-norm', 'Upper', N, DWORK, N, DWORK( ITMP+1 ))
-     $          .GE.
-     $          DLANSY( '1-norm', 'Lower', N, DWORK, N, DWORK( ITMP+1 ))
-     $        ) THEN
-               LOUP = 'U'
-            ELSE
-               LOUP = 'L'
-            END IF
-C
-C           Compute RHS = X*W*X.
-C
-            CALL MB01RU( LOUP, 'No Transpose', N, N, ZERO, ONE, DWORK,
-     $                   N, X, LDX, DWORK, N, DWORK( ITMP+1 ), NN,
-     $                   INFO2 )
-            CALL DSCAL( N, HALF, DWORK, N+1 )
-C
-            IF( UPDATE ) THEN
-C
-C              Transform the right-hand side: RHS := U'*RHS*U.
-C
-               CALL MB01RU( LOUP, 'Transpose', N, N, ZERO, ONE, DWORK,
-     $                      N, U, LDU, DWORK, N, DWORK( ITMP+1 ), NN,
-     $                      INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-            END IF
-C
-C           Fill in the remaining triangle of the symmetric matrix.
-C
-            CALL MA02ED( LOUP, N, DWORK, N )
-C
-            IF( KASE.EQ.1 ) THEN
-C
-C              Solve op(T)'*Y + Y*op(T) = scale*RHS.
-C
-               CALL SB03MY( TRANA, N, T, LDT, DWORK, N, SCALE, INFO2 )
-            ELSE
-C
-C              Solve op(T)*W + W*op(T)' = scale*RHS.
-C
-               CALL SB03MY( TRANAT, N, T, LDT, DWORK, N, SCALE, INFO2 )
-            END IF
-C
-            IF( UPDATE ) THEN
-C
-C              Transform back to obtain the solution: Z := U*Z*U', with
-C              Z = Y or Z = W.
-C
-               CALL MB01RU( LOUP, 'No transpose', N, N, ZERO, ONE,
-     $                      DWORK, N, U, LDU, DWORK, N, DWORK( ITMP+1 ),
-     $                      NN, INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-C
-C              Fill in the remaining triangle of the symmetric matrix.
-C
-               CALL MA02ED( LOUP, N, DWORK, N )
-            END IF
-            GO TO 10
-         END IF
-C        UNTIL KASE = 0
-C
-         IF( EST.LT.SCALE ) THEN
-            PINORM = EST / SCALE
-         ELSE
-            BIGNUM = ONE / DLAMCH( 'Safe minimum' )
-            IF( EST.LT.SCALE*BIGNUM ) THEN
-               PINORM = EST / SCALE
-            ELSE
-               PINORM = BIGNUM
-            END IF
-         END IF
-C
-C        Compute the 1-norm of A or T.
-C
-         IF( UPDATE ) THEN
-            ANORM = DLANGE( '1-norm', N, N, A, LDA, DWORK )
-         ELSE
-            ANORM = DLANHS( '1-norm', N, T, LDT, DWORK )
-         END IF
-C
-C        Compute the 1-norms of the matrices Q and G.
-C
-         QNORM = DLANSY( '1-norm', UPLO, N, Q, LDQ, DWORK )
-         GNORM = DLANSY( '1-norm', UPLO, N, G, LDG, DWORK )
-C
-C        Estimate the reciprocal condition number.
-C
-         TMAX = MAX( SEP, XNORM, ANORM, GNORM )
-         IF( TMAX.LE.ONE ) THEN
-            TEMP  = SEP*XNORM
-            DENOM = QNORM + ( SEP*ANORM )*THNORM +
-     $                      ( SEP*GNORM )*PINORM
-         ELSE
-            TEMP  =   ( SEP / TMAX )*( XNORM / TMAX )
-            DENOM = ( ( ONE / TMAX )*( QNORM / TMAX ) ) +
-     $              ( ( SEP / TMAX )*( ANORM / TMAX ) )*THNORM +
-     $              ( ( SEP / TMAX )*( GNORM / TMAX ) )*PINORM
-         END IF
-         IF( TEMP.GE.DENOM ) THEN
-            RCOND = ONE
-         ELSE
-            RCOND = TEMP / DENOM
-         END IF
-      END IF
-C
-      IF( .NOT.JOBC ) THEN
-C
-C        Form a triangle of the residual matrix
-C          R = op(A)'*X + X*op(A) + Q - X*G*X,
-C        or           _   _         _   _ _ _
-C          R = op(T)'*X + X*op(T) + Q + X*G*X,
-C        exploiting the symmetry.
-C        Workspace 4*N*N.
-C
-         IF( UPDATE ) THEN
-            CALL DLACPY( UPLO, N, N, Q, LDQ, DWORK( IRES+1 ), N )
-            CALL DSYR2K( UPLO, TRANAT, N, N, ONE, A, LDA, X, LDX, ONE,
-     $                   DWORK( IRES+1 ), N )
-            SIG = -ONE
-         ELSE
-            CALL MB01UD( 'Right', TRANA, N, N, ONE, T, LDT, X, LDX,
-     $                   DWORK( IRES+1 ), N, INFO2 )
-            JJ = IRES + 1
-            IF( LOWER ) THEN
-               DO 20 J = 1, N
-                  CALL DAXPY( N-J+1, ONE, DWORK( JJ ), N, DWORK( JJ ),
-     $                        1 )
-                  CALL DAXPY( N-J+1, ONE, Q( J, J ), 1, DWORK( JJ ), 1 )
-                  JJ = JJ + N + 1
-   20          CONTINUE
-            ELSE
-               DO 30 J = 1, N
-                  CALL DAXPY( J, ONE, DWORK( IRES+J ), N, DWORK( JJ ),
-     $                        1 )
-                  CALL DAXPY( J, ONE, Q( 1, J ), 1, DWORK( JJ ), 1 )
-                  JJ = JJ + N
-   30          CONTINUE
-            END IF
-            SIG = ONE
-         END IF
-         CALL MB01RU( UPLO, TRANAT, N, N, ONE, SIG, DWORK( IRES+1 ),
-     $                N, X, LDX, G, LDG, DWORK( ITMP+1 ), NN, INFO2 )
-C
-C        Get the machine precision.
-C
-         EPS  = DLAMCH( 'Epsilon' )
-         EPSN = EPS*DBLE( N + 4 )
-         TEMP = EPS*FOUR
-C
-C        Add to abs(R) a term that takes account of rounding errors in
-C        forming R:
-C         abs(R) := abs(R) + EPS*(4*abs(Q) + (n+4)*(abs(op(Ac))'*abs(X)
-C                 + abs(X)*abs(op(Ac))) + 2*(n+1)*abs(X)*abs(G)*abs(X)),
-C        or                             _                           _
-C         abs(R) := abs(R) + EPS*(4*abs(Q) + (n+4)*(abs(op(T))'*abs(X)
-C                       _                            _      _      _
-C                 + abs(X)*abs(op(T))) + 2*(n+1)*abs(X)*abs(G)*abs(X)),
-C        where EPS is the machine precision.
-C
-         DO 50 J = 1, N
-            DO 40 I = 1, N
-               DWORK( IXBS+(J-1)*N+I ) = ABS( X( I, J ) )
-   40       CONTINUE
-   50    CONTINUE
-C
-         IF( LOWER ) THEN
-            DO 70 J = 1, N
-               DO 60 I = J, N
-                  DWORK( IRES+(J-1)*N+I ) = TEMP*ABS( Q( I, J ) ) +
-     $                   ABS( DWORK( IRES+(J-1)*N+I ) )
-   60          CONTINUE
-   70       CONTINUE
-         ELSE
-            DO 90 J = 1, N
-               DO 80 I = 1, J
-                  DWORK( IRES+(J-1)*N+I ) = TEMP*ABS( Q( I, J ) ) +
-     $                   ABS( DWORK( IRES+(J-1)*N+I ) )
-   80          CONTINUE
-   90       CONTINUE
-         END IF
-C
-         IF( UPDATE ) THEN
-C
-            DO 110 J = 1, N
-               DO 100 I = 1, N
-                  DWORK( IABS+(J-1)*N+I ) =
-     $               ABS( DWORK( IABS+(J-1)*N+I ) )
-  100          CONTINUE
-  110       CONTINUE
-C
-            CALL DSYR2K( UPLO, TRANAT, N, N, EPSN, DWORK( IABS+1 ), N,
-     $                   DWORK( IXBS+1 ), N, ONE,  DWORK( IRES+1 ), N )
-         ELSE
-C
-            DO 130 J = 1, N
-               DO 120 I = 1, MIN( J+1, N )
-                  DWORK( IABS+(J-1)*N+I ) = ABS( T( I, J ) )
-  120          CONTINUE
-  130       CONTINUE
-C
-            CALL MB01UD( 'Left', TRANAT, N, N, EPSN, DWORK( IABS+1 ), N,
-     $                   DWORK( IXBS+1), N, DWORK( ITMP+1 ), N, INFO2 )
-            JJ = IRES + 1
-            JX = ITMP + 1
-            IF( LOWER ) THEN
-               DO 140 J = 1, N
-                  CALL DAXPY( N-J+1, ONE, DWORK( JX ), N, DWORK( JX ),
-     $                        1 )
-                  CALL DAXPY( N-J+1, ONE, DWORK( JX ), 1, DWORK( JJ ),
-     $                        1 )
-                  JJ = JJ + N + 1
-                  JX = JX + N + 1
-  140          CONTINUE
-            ELSE
-               DO 150 J = 1, N
-                  CALL DAXPY( J, ONE, DWORK( ITMP+J ), N, DWORK( JX ),
-     $                        1 )
-                  CALL DAXPY( J, ONE, DWORK( JX ), 1, DWORK( JJ ), 1 )
-                  JJ = JJ + N
-                  JX = JX + N
-  150          CONTINUE
-            END IF
-         END IF
-C
-         IF( LOWER ) THEN
-            DO 170 J = 1, N
-               DO 160 I = J, N
-                  DWORK( IABS+(J-1)*N+I ) = ABS( G( I, J ) )
-  160          CONTINUE
-  170       CONTINUE
-         ELSE
-            DO 190 J = 1, N
-               DO 180 I = 1, J
-                  DWORK( IABS+(J-1)*N+I ) = ABS( G( I, J ) )
-  180          CONTINUE
-  190       CONTINUE
-         END IF
-C
-         CALL MB01RU( UPLO, TRANA, N, N, ONE, EPS*DBLE( 2*( N + 1 ) ),
-     $                DWORK( IRES+1 ), N, DWORK( IXBS+1), N,
-     $                DWORK( IABS+1 ), N, DWORK( ITMP+1 ), NN, INFO2 )
-C
-         WRKOPT = MAX( WRKOPT, 4*NN )
-C
-C        Compute forward error bound, using matrix norm estimator.
-C        Workspace 4*N*N.
-C
-         XANORM = DLANSY( 'Max', UPLO, N, X, LDX, DWORK )
-C
-         CALL SB03QX( TRANA, UPLO, LYAPUN, N, XANORM, T, LDT, U, LDU,
-     $                DWORK( IRES+1 ), N, FERR, IWORK, DWORK, IRES,
-     $                INFO )
-      END IF
-C
-      DWORK( 1 ) = DBLE( WRKOPT )
-      RETURN
-C
-C *** Last line of SB02QD ***
-      END
--- a/extra/control-devel/src/SB02RD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1133 +0,0 @@
-      SUBROUTINE SB02RD( JOB, DICO, HINV, TRANA, UPLO, SCAL, SORT, FACT,
-     $                   LYAPUN, N, A, LDA, T, LDT, V, LDV, G, LDG, Q,
-     $                   LDQ, X, LDX, SEP, RCOND, FERR, WR, WI, S, LDS,
-     $                   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 + op(A)'*X + X*op(A) - X*op(B)*R  op(B)'*X = 0,           (1)
-C
-C     or the discrete-time algebraic Riccati equation
-C                                                                -1
-C        X = op(A)'*X*op(A) - op(A)'*X*op(B)*(R + op(B)'*X*op(B))  *
-C                             op(B)'*X*op(A) + Q,                    (2)
-C
-C     where op(M) = M or M' (M**T), A, op(B), Q, and R are N-by-N,
-C     N-by-M, N-by-N, and M-by-M matrices respectively, with Q symmetric
-C     and R symmetric nonsingular; X is an N-by-N symmetric matrix.
-C                           -1
-C     The matrix G = op(B)*R  *op(B)' must be provided on input, instead
-C     of B and R, that is, the continuous-time equation
-C
-C        Q + op(A)'*X + X*op(A) - X*G*X = 0,                         (3)
-C
-C     or the discrete-time equation
-C                                -1
-C        Q + op(A)'*X*(I_n + G*X)  *op(A) - X = 0,                   (4)
-C
-C     are solved, where G is an N-by-N symmetric matrix. SLICOT Library
-C     routine SB02MT should be used to compute G, given B and R. SB02MT
-C     also enables to solve Riccati equations corresponding to optimal
-C     problems with coupling terms.
-C
-C     The routine also returns the computed values of the closed-loop
-C     spectrum of the optimal system, i.e., the stable eigenvalues
-C     lambda(1),...,lambda(N) of the corresponding Hamiltonian or
-C     symplectic matrix associated to the optimal problem. It is assumed
-C     that the matrices A, G, and Q are such that the associated
-C     Hamiltonian or symplectic matrix has N stable eigenvalues, i.e.,
-C     with negative real parts, in the continuous-time case, and with
-C     moduli less than one, in the discrete-time case.
-C
-C     Optionally, estimates of the conditioning and error bound on the
-C     solution of the Riccati equation (3) or (4) are returned.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies the computation to be performed, as follows:
-C             = 'X':  Compute the solution only;
-C             = 'C':  Compute the reciprocal condition number only;
-C             = 'E':  Compute the error bound only;
-C             = 'A':  Compute all: the solution, reciprocal condition
-C                     number, and the error bound.
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of Riccati equation to be solved or
-C             analyzed, as follows:
-C             = 'C':  Equation (3), continuous-time case;
-C             = 'D':  Equation (4), discrete-time case.
-C
-C     HINV    CHARACTER*1
-C             If DICO = 'D' and JOB = 'X' or JOB = 'A', specifies which
-C             symplectic matrix is to be constructed, as follows:
-C             = 'D':  The matrix H in (6) (see METHOD) is constructed;
-C             = 'I':  The inverse of the matrix H in (6) is constructed.
-C             HINV is not used if DICO = 'C', or JOB = 'C' or 'E'.
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     UPLO    CHARACTER*1
-C             Specifies which triangle of the matrices G and Q is
-C             stored, as follows:
-C             = 'U':  Upper triangle is stored;
-C             = 'L':  Lower triangle is stored.
-C
-C     SCAL    CHARACTER*1
-C             If JOB = 'X' or JOB = 'A', specifies whether or not a
-C             scaling strategy should be used, as follows:
-C             = 'G':  General scaling should be used;
-C             = 'N':  No scaling should be used.
-C             SCAL is not used if JOB = 'C' or 'E'.
-C
-C     SORT    CHARACTER*1
-C             If JOB = 'X' or JOB = 'A', specifies which eigenvalues
-C             should be obtained in the top of the Schur form, as
-C             follows:
-C             = 'S':  Stable   eigenvalues come first;
-C             = 'U':  Unstable eigenvalues come first.
-C             SORT is not used if JOB = 'C' or 'E'.
-C
-C     FACT    CHARACTER*1
-C             If JOB <> 'X', specifies whether or not a real Schur
-C             factorization of the closed-loop system matrix Ac is
-C             supplied on entry, as follows:
-C             = 'F':  On entry, T and V contain the factors from a real
-C                     Schur factorization of the matrix Ac;
-C             = 'N':  A Schur factorization of Ac will be computed
-C                     and the factors will be stored in T and V.
-C             For a continuous-time system, the matrix Ac is given by
-C                Ac = A - G*X, if TRANA = 'N', or
-C                Ac = A - X*G, if TRANA = 'T' or 'C',
-C             and for a discrete-time system, the matrix Ac is given by
-C                Ac = inv(I_n + G*X)*A, if TRANA = 'N', or
-C                Ac = A*inv(I_n + X*G), if TRANA = 'T' or 'C'.
-C             FACT is not used if JOB = 'X'.
-C
-C     LYAPUN  CHARACTER*1
-C             If JOB <> 'X', specifies whether or not the original or
-C             "reduced" Lyapunov equations should be solved for
-C             estimating reciprocal condition number and/or the error
-C             bound, as follows:
-C             = 'O':  Solve the original Lyapunov equations, updating
-C                     the right-hand sides and solutions with the
-C                     matrix V, e.g., X <-- V'*X*V;
-C             = 'R':  Solve reduced Lyapunov equations only, without
-C                     updating the right-hand sides and solutions.
-C                     This means that a real Schur form T of Ac appears
-C                     in the equations, instead of Ac.
-C             LYAPUN is not used if JOB = 'X'.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A, Q, G, and X.  N >= 0.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,N)
-C             If JOB = 'X' or JOB = 'A' or FACT = 'N' or LYAPUN = 'O',
-C             the leading N-by-N part of this array must contain the
-C             coefficient matrix A of the equation.
-C             If JOB = 'C' or 'E' and FACT = 'F' and LYAPUN = 'R', A is
-C             not referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.
-C             LDA >= MAX(1,N), if JOB  = 'X' or JOB = 'A' or
-C                                 FACT = 'N' or LYAPUN = 'O'.
-C             LDA >= 1,        otherwise.
-C
-C     T       (input or output) DOUBLE PRECISION array, dimension
-C             (LDT,N)
-C             If JOB <> 'X' and FACT = 'F', then T is an input argument
-C             and on entry, the leading N-by-N upper Hessenberg part of
-C             this array must contain the upper quasi-triangular matrix
-C             T in Schur canonical form from a Schur factorization of Ac
-C             (see argument FACT).
-C             If JOB <> 'X' and FACT = 'N', then T is an output argument
-C             and on exit, if INFO = 0 or INFO = 7, the leading N-by-N
-C             upper Hessenberg part of this array contains the upper
-C             quasi-triangular matrix T in Schur canonical form from a
-C             Schur factorization of Ac (see argument FACT).
-C             If JOB = 'X', the array T is not referenced.
-C
-C     LDT     INTEGER
-C             The leading dimension of the array T.
-C             LDT >= 1,        if JOB =  'X';
-C             LDT >= MAX(1,N), if JOB <> 'X'.
-C
-C     V       (input or output) DOUBLE PRECISION array, dimension
-C             (LDV,N)
-C             If JOB <> 'X' and FACT = 'F', then V is an input argument
-C             and on entry, the leading N-by-N part of this array must
-C             contain the orthogonal matrix V from a real Schur
-C             factorization of Ac (see argument FACT).
-C             If JOB <> 'X' and FACT = 'N', then V is an output argument
-C             and on exit, if INFO = 0 or INFO = 7, the leading N-by-N
-C             part of this array contains the orthogonal N-by-N matrix
-C             from a real Schur factorization of Ac (see argument FACT).
-C             If JOB = 'X', the array V is not referenced.
-C
-C     LDV     INTEGER
-C             The leading dimension of the array V.
-C             LDV >= 1,        if JOB =  'X';
-C             LDV >= MAX(1,N), if JOB <> 'X'.
-C
-C     G       (input/output) DOUBLE PRECISION array, dimension (LDG,N)
-C             On entry, the leading N-by-N upper triangular part (if
-C             UPLO = 'U') or lower triangular part (if UPLO = 'L') of
-C             this array must contain the upper triangular part or lower
-C             triangular part, respectively, of the symmetric matrix G.
-C             On exit, if JOB = 'X' and DICO = 'D', or JOB <> 'X' and
-C             LYAPUN = 'R', the leading N-by-N part of this array
-C             contains the symmetric matrix G fully stored.
-C             If JOB <> 'X' and LYAPUN = 'R', this array is modified
-C             internally, but restored on exit.
-C
-C     LDG     INTEGER
-C             The leading dimension of the array G.  LDG >= MAX(1,N).
-C
-C     Q       (input/output) DOUBLE PRECISION array, dimension (LDQ,N)
-C             On entry, the leading N-by-N upper triangular part (if
-C             UPLO = 'U') or lower triangular part (if UPLO = 'L') of
-C             this array must contain the upper triangular part or lower
-C             triangular part, respectively, of the symmetric matrix Q.
-C             On exit, if JOB = 'X' and DICO = 'D', or JOB <> 'X' and
-C             LYAPUN = 'R', the leading N-by-N part of this array
-C             contains the symmetric matrix Q fully stored.
-C             If JOB <> 'X' and LYAPUN = 'R', this array is modified
-C             internally, but restored on exit.
-C
-C     LDQ     INTEGER
-C             The leading dimension of the array Q.  LDQ >= MAX(1,N).
-C
-C     X       (input or output) DOUBLE PRECISION array, dimension
-C             (LDX,N)
-C             If JOB = 'C' or JOB = 'E', then X is an input argument
-C             and on entry, the leading N-by-N part of this array must
-C             contain the symmetric solution matrix of the algebraic
-C             Riccati equation. If LYAPUN = 'R', this array is modified
-C             internally, but restored on exit; however, it could differ
-C             from the input matrix at the round-off error level.
-C             If JOB = 'X' or JOB = 'A', then X is an output argument
-C             and on exit, if INFO = 0 or INFO >= 6, the leading N-by-N
-C             part of this array contains the symmetric solution matrix
-C             X of the algebraic Riccati equation.
-C
-C     LDX     INTEGER
-C             The leading dimension of the array X.  LDX >= MAX(1,N).
-C
-C     SEP     (output) DOUBLE PRECISION
-C             If JOB = 'C' or JOB = 'A', and INFO = 0 or INFO = 7, the
-C             estimated quantity
-C                sep(op(Ac),-op(Ac)'), if DICO = 'C', or
-C                sepd(op(Ac),op(Ac)'), if DICO = 'D'. (See METHOD.)
-C             If JOB = 'C' or JOB = 'A' and X = 0, or JOB = 'E', SEP is
-C             not referenced.
-C             If JOB = 'X', and INFO = 0, INFO = 5 or INFO = 7,
-C             SEP contains the scaling factor used, which should
-C             multiply the (2,1) submatrix of U to recover X from the
-C             first N columns of U (see METHOD). If SCAL = 'N', SEP is
-C             set to 1.
-C
-C     RCOND   (output) DOUBLE PRECISION
-C             If JOB = 'C' or JOB = 'A', and INFO = 0 or INFO = 7, an
-C             estimate of the reciprocal condition number of the
-C             algebraic Riccati equation.
-C             If N = 0 or X = 0, RCOND is set to 1 or 0, respectively.
-C             If JOB = 'X', or JOB = 'E', RCOND is not referenced.
-C
-C     FERR    (output) DOUBLE PRECISION
-C             If JOB = 'E' or JOB = 'A', and INFO = 0 or INFO = 7, an
-C             estimated forward error bound for the solution X. If XTRUE
-C             is the true solution, FERR bounds the magnitude of the
-C             largest entry in (X - XTRUE) divided by the magnitude of
-C             the largest entry in X.
-C             If N = 0 or X = 0, FERR is set to 0.
-C             If JOB = 'X', or JOB = 'C', FERR is not referenced.
-C
-C     WR      (output) DOUBLE PRECISION array, dimension (2*N)
-C     WI      (output) DOUBLE PRECISION array, dimension (2*N)
-C             If JOB = 'X' or JOB = 'A', and INFO = 0 or INFO >= 5,
-C             these arrays contain the real and imaginary parts,
-C             respectively, of the eigenvalues of the 2N-by-2N matrix S,
-C             ordered as specified by SORT (except for the case
-C             HINV = 'D', when the order is opposite to that specified
-C             by SORT). The leading N elements of these arrays contain
-C             the closed-loop spectrum of the system matrix Ac (see
-C             argument FACT). Specifically,
-C                lambda(k) = WR(k) + j*WI(k), for k = 1,2,...,N.
-C             If JOB = 'C' or JOB = 'E', these arrays are not
-C             referenced.
-C
-C     S       (output) DOUBLE PRECISION array, dimension (LDS,2*N)
-C             If JOB = 'X' or JOB = 'A', and INFO = 0 or INFO >= 5, the
-C             leading 2N-by-2N part of this array contains the ordered
-C             real Schur form S of the (scaled, if SCAL = 'G')
-C             Hamiltonian or symplectic matrix H. 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             If JOB = 'C' or JOB = 'E', this array is not referenced.
-C
-C     LDS     INTEGER
-C             The leading dimension of the array S.
-C             LDS >= MAX(1,2*N), if JOB = 'X' or JOB = 'A';
-C             LDS >= 1,          if JOB = 'C' or JOB = 'E'.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK >= 2*N,          if JOB = 'X';
-C             LIWORK >= N*N,          if JOB = 'C' or JOB = 'E';
-C             LIWORK >= MAX(2*N,N*N), if JOB = 'A'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, or INFO = 7, DWORK(1) returns the
-C             optimal value of LDWORK. If INFO = 0, or INFO >= 5, and
-C             JOB = 'X', or JOB = 'A', then DWORK(2) returns an estimate
-C             RCONDU of the reciprocal of the condition number (in the
-C             1-norm) of the N-th order system of algebraic equations
-C             from which the solution matrix X is obtained, and DWORK(3)
-C             returns the reciprocal pivot growth factor for the LU
-C             factorization of the coefficient matrix of that system
-C             (see SLICOT Library routine MB02PD); if DWORK(3) is much
-C             less than 1, then the computed X and RCONDU could be
-C             unreliable.
-C             If DICO = 'D', and JOB = 'X', or JOB = 'A', then DWORK(4)
-C             returns the reciprocal condition number RCONDA of the
-C             given matrix A, and DWORK(5) returns the reciprocal pivot
-C             growth factor for A or for its leading columns, if A is
-C             singular (see SLICOT Library routine MB02PD); if DWORK(5)
-C             is much less than 1, then the computed S and RCONDA could
-C             be unreliable.
-C             On exit, if INFO = 0, or INFO >= 4, and JOB = 'X', the
-C             elements DWORK(6:5+4*N*N) contain the 2*N-by-2*N
-C             transformation matrix  U  which reduced the Hamiltonian or
-C             symplectic matrix  H  to the ordered real Schur form  S.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 5+MAX(1,4*N*N+8*N), if JOB = 'X' or JOB = 'A';
-C             This may also be used for JOB = 'C' or JOB = 'E', but
-C             exact bounds are as follows:
-C             LDWORK >= 5 + MAX(1,LWS,LWE) + LWN, where
-C             LWS = 0,       if FACT = 'F' or  LYAPUN = 'R';
-C                 = 5*N,     if FACT = 'N' and LYAPUN = 'O' and
-C                                              DICO = 'C' and JOB = 'C';
-C                 = 5*N+N*N, if FACT = 'N' and LYAPUN = 'O' and
-C                                              DICO = 'C' and JOB = 'E';
-C                 = 5*N+N*N, if FACT = 'N' and LYAPUN = 'O' and
-C                                              DICO = 'D';
-C             LWE = 2*N*N,                if DICO = 'C' and JOB = 'C';
-C                 = 4*N*N,                if DICO = 'C' and JOB = 'E';
-C                 = MAX(3,2*N*N) + N*N,   if DICO = 'D' and JOB = 'C';
-C                 = MAX(3,2*N*N) + 2*N*N, if DICO = 'D' and JOB = 'E';
-C             LWN = 0,   if LYAPUN = 'O' or   JOB = 'C';
-C                 = 2*N, if LYAPUN = 'R' and DICO = 'C' and JOB = 'E';
-C                 = 3*N, if LYAPUN = 'R' and DICO = 'D' and JOB = 'E'.
-C             For optimum performance LDWORK should sometimes be larger.
-C
-C     BWORK   LOGICAL array, dimension (LBWORK)
-C             LBWORK >= 2*N,          if JOB = 'X' or JOB = 'A';
-C             LBWORK >= 1,            if JOB = 'C' or JOB = 'E', and
-C                                     FACT = 'N' and LYAPUN = 'R';
-C             LBWORK >= 0,            otherwise.
-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 matrix A is (numerically) singular in discrete-
-C                   time case;
-C             = 2:  if the Hamiltonian or symplectic matrix H cannot be
-C                   reduced to real Schur form;
-C             = 3:  if the real Schur form of the Hamiltonian or
-C                   symplectic matrix H cannot be appropriately ordered;
-C             = 4:  if the Hamiltonian or symplectic matrix H has less
-C                   than N stable eigenvalues;
-C             = 5:  if the N-th order system of linear algebraic
-C                   equations, from which the solution matrix X would
-C                   be obtained, is singular to working precision;
-C             = 6:  if the QR algorithm failed to complete the reduction
-C                   of the matrix Ac to Schur canonical form, T;
-C             = 7:  if T and -T' have some almost equal eigenvalues, if
-C                   DICO = 'C', or T has almost reciprocal eigenvalues,
-C                   if DICO = 'D'; perturbed values were used to solve
-C                   Lyapunov equations, but the matrix T, if given (for
-C                   FACT = 'F'), is unchanged. (This is a warning
-C                   indicator.)
-C
-C     METHOD
-C
-C     The method used is the Schur vector approach proposed by Laub [1],
-C     but with an optional scaling, which enhances the numerical
-C     stability [6]. It is assumed that [A,B] is a stabilizable pair
-C     (where for (3) or (4), B is any matrix such that B*B' = G with
-C     rank(B) = rank(G)), and [E,A] is a detectable pair, where E is any
-C     matrix such that E*E' = Q with rank(E) = rank(Q). Under these
-C     assumptions, any of the algebraic Riccati equations (1)-(4) is
-C     known to have a unique non-negative definite solution. See [2].
-C     Now consider the 2N-by-2N Hamiltonian or symplectic matrix
-C
-C                 ( op(A)   -G    )
-C            H =  (               ),                                 (5)
-C                 (  -Q   -op(A)' ),
-C
-C     for continuous-time equation, and
-C                         -1              -1
-C                 (  op(A)           op(A)  *G       )
-C            H =  (        -1                   -1   ),              (6)
-C                 ( Q*op(A)     op(A)' + Q*op(A)  *G )
-C
-C     for discrete-time equation, respectively, where
-C                       -1
-C            G = op(B)*R  *op(B)'.
-C     The assumptions guarantee that H in (5) has no pure imaginary
-C     eigenvalues, and H in (6) has no eigenvalues on the unit circle.
-C     If Y is an N-by-N matrix then there exists an orthogonal matrix U
-C     such that U'*Y*U is an upper quasi-triangular matrix. Moreover, U
-C     can be chosen so that the 2-by-2 and 1-by-1 diagonal blocks
-C     (corresponding to the complex conjugate eigenvalues and real
-C     eigenvalues respectively) appear in any desired order. This is the
-C     ordered real Schur form. Thus, we can find an orthogonal
-C     similarity transformation U which puts (5) or (6) in ordered real
-C     Schur form
-C
-C            U'*H*U = S = (S(1,1)  S(1,2))
-C                         (  0     S(2,2))
-C
-C     where S(i,j) is an N-by-N matrix and the eigenvalues of S(1,1)
-C     have negative real parts in case of (5), or moduli greater than
-C     one in case of (6). If U is conformably partitioned into four
-C     N-by-N blocks
-C
-C               U = (U(1,1)  U(1,2))
-C                   (U(2,1)  U(2,2))
-C
-C     with respect to the assumptions we then have
-C     (a) U(1,1) is invertible and X = U(2,1)*inv(U(1,1)) solves (1),
-C         (2), (3), or (4) with X = X' and non-negative definite;
-C     (b) the eigenvalues of S(1,1) (if DICO = 'C') or S(2,2) (if
-C         DICO = 'D') are equal to the eigenvalues of optimal system
-C         (the 'closed-loop' spectrum).
-C
-C     [A,B] is stabilizable if there exists a matrix F such that (A-BF)
-C     is stable. [E,A] is detectable if [A',E'] is stabilizable.
-C
-C     The condition number of a Riccati equation is estimated as
-C
-C     cond = ( norm(Theta)*norm(A) + norm(inv(Omega))*norm(Q) +
-C                 norm(Pi)*norm(G) ) / norm(X),
-C
-C     where Omega, Theta and Pi are linear operators defined by
-C
-C     Omega(W) = op(Ac)'*W + W*op(Ac),
-C     Theta(W) = inv(Omega(op(W)'*X + X*op(W))),
-C        Pi(W) = inv(Omega(X*W*X)),
-C
-C     in the continuous-time case, and
-C
-C     Omega(W) = op(Ac)'*W*op(Ac) - W,
-C     Theta(W) = inv(Omega(op(W)'*X*op(Ac) + op(Ac)'X*op(W))),
-C        Pi(W) = inv(Omega(op(Ac)'*X*W*X*op(Ac))),
-C
-C     in the discrete-time case, and Ac has been defined (see argument
-C     FACT). Details are given in the comments of SLICOT Library
-C     routines SB02QD and SB02SD.
-C
-C     The routine estimates the quantities
-C
-C     sep(op(Ac),-op(Ac)') = 1 / norm(inv(Omega)),
-C     sepd(op(Ac),op(Ac)') = 1 / norm(inv(Omega)),
-C
-C     norm(Theta) and norm(Pi) using 1-norm condition estimator.
-C
-C     The forward error bound is estimated using a practical error bound
-C     similar to the one proposed in [5].
-C
-C     REFERENCES
-C
-C     [1] Laub, A.J.
-C         A Schur Method for Solving Algebraic Riccati equations.
-C         IEEE Trans. Auto. Contr., AC-24, pp. 913-921, 1979.
-C
-C     [2] Wonham, W.M.
-C         On a matrix Riccati equation of stochastic control.
-C         SIAM J. Contr., 6, pp. 681-697, 1968.
-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     [4] Ghavimi, A.R. and Laub, A.J.
-C         Backward error, sensitivity, and refinement of computed
-C         solutions of algebraic Riccati equations.
-C         Numerical Linear Algebra with Applications, vol. 2, pp. 29-49,
-C         1995.
-C
-C     [5] Higham, N.J.
-C         Perturbation theory and backward error for AX-XB=C.
-C         BIT, vol. 33, pp. 124-136, 1993.
-C
-C     [6] Petkov, P.Hr., Konstantinov, M.M., and Mehrmann, V.
-C         DGRSVX and DMSRIC: Fortran 77 subroutines for solving
-C         continuous-time matrix algebraic Riccati equations with
-C         condition and accuracy estimates.
-C         Preprint SFB393/98-16, Fak. f. Mathematik, Tech. Univ.
-C         Chemnitz, May 1998.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations. The solution accuracy
-C     can be controlled by the output parameter FERR.
-C
-C     FURTHER COMMENTS
-C
-C     To obtain a stabilizing solution of the algebraic Riccati
-C     equation for DICO = 'D', set SORT = 'U', if HINV = 'D', or set
-C     SORT = 'S', if HINV = 'I'.
-C
-C     The routine can also compute the anti-stabilizing solutions of
-C     the algebraic Riccati equations, by specifying
-C         SORT = 'U' if DICO = 'D' and HINV = 'I', or DICO = 'C', or
-C         SORT = 'S' if DICO = 'D' and HINV = 'D'.
-C
-C     Usually, the combinations HINV = 'D' and SORT = 'U', or HINV = 'I'
-C     and SORT = 'U', for stabilizing and anti-stabilizing solutions,
-C     respectively, will be faster then the other combinations [3].
-C
-C     The option LYAPUN = 'R' may produce slightly worse or better
-C     estimates, and it is faster than the option 'O'.
-C
-C     This routine is a functionally extended and more accurate
-C     version of the SLICOT Library routine SB02MD. Transposed problems
-C     can be dealt with as well. Iterative refinement is used whenever
-C     useful to solve linear algebraic systems. Condition numbers and
-C     error bounds on the solutions are optionally provided.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 1999.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2001,
-C     Dec. 2002, Oct. 2004.
-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
-      PARAMETER         ( ZERO = 0.0D0, HALF = 0.5D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, FACT, HINV, JOB, LYAPUN, SCAL, SORT,
-     $                  TRANA, UPLO
-      INTEGER           INFO, LDA, LDG, LDQ, LDS, LDT, LDV, LDWORK, LDX,
-     $                  N
-      DOUBLE PRECISION  FERR, RCOND, SEP
-C     .. Array Arguments ..
-      LOGICAL           BWORK(*)
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), DWORK(*), G(LDG,*), Q(LDQ,*),
-     $                  S(LDS,*), T(LDT,*), V(LDV,*), WI(*), WR(*),
-     $                  X(LDX,*)
-C     .. Local Scalars ..
-      LOGICAL           COLEQU, DISCR, JBXA, JOBA, JOBC, JOBE, JOBX,
-     $                  LHINV, LSCAL, LSCL, LSORT, LUPLO, NOFACT,
-     $                  NOTRNA, ROWEQU, UPDATE
-      CHARACTER         EQUED, JOBS, LOFACT, LOUP, TRANAT
-      INTEGER           I, IERR, IU, IW, IWB, IWC, IWF, IWI, IWR, LDW,
-     $                  LWE, LWN, LWS, N2, NN, NP1, NROT
-      DOUBLE PRECISION  GNORM, QNORM, PIVOTA, PIVOTU, RCONDA, RCONDU,
-     $                  WRKOPT
-C     .. External Functions ..
-      LOGICAL           LSAME, SB02MR, SB02MS, SB02MV, SB02MW
-      DOUBLE PRECISION  DLAMCH, DLANGE, DLANSY
-      EXTERNAL          DLAMCH, DLANGE, DLANSY, LSAME, SB02MR, SB02MS,
-     $                  SB02MV, SB02MW
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DCOPY, DGEES, DGESV, DLACPY, DLASCL,
-     $                  DLASET, DSCAL, DSWAP, DSYMM, MA02AD, MA02ED,
-     $                  MB01RU, MB01SD, MB02PD, SB02QD, SB02RU, SB02SD,
-     $                  XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, MAX
-C     .. Executable Statements ..
-C
-C     Decode the input parameters.
-C
-      N2  = N + N
-      NN  = N*N
-      NP1 = N + 1
-      INFO = 0
-      JOBA   = LSAME( JOB,    'A' )
-      JOBC   = LSAME( JOB,    'C' )
-      JOBE   = LSAME( JOB,    'E' )
-      JOBX   = LSAME( JOB,    'X' )
-      NOFACT = LSAME( FACT,   'N' )
-      NOTRNA = LSAME( TRANA,  'N' )
-      DISCR  = LSAME( DICO,   'D' )
-      LUPLO  = LSAME( UPLO,   'U' )
-      LSCAL  = LSAME( SCAL,   'G' )
-      LSORT  = LSAME( SORT,   'S' )
-      UPDATE = LSAME( LYAPUN, 'O' )
-      JBXA   = JOBX .OR. JOBA
-      LHINV  = .FALSE.
-      IF ( DISCR .AND. JBXA )
-     $   LHINV = LSAME( HINV, 'D' )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.( JBXA .OR. JOBC .OR. JOBE ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( DISCR .OR. LSAME( DICO, 'C' ) ) ) THEN
-         INFO = -2
-      ELSE IF( DISCR .AND. JBXA ) THEN
-         IF( .NOT.( LHINV .OR. LSAME( HINV, 'I' ) ) )
-     $      INFO = -3
-      END IF
-      IF( INFO.EQ.0 ) THEN
-         IF( .NOT.( NOTRNA .OR. LSAME( TRANA, 'T' ) .OR.
-     $                          LSAME( TRANA, 'C' ) ) ) THEN
-            INFO = -4
-         ELSE IF( .NOT.( LUPLO .OR. LSAME( UPLO, 'L' ) ) )
-     $      THEN
-            INFO = -5
-         ELSE IF( JBXA ) THEN
-            IF( .NOT.( LSCAL .OR. LSAME( SCAL, 'N' ) ) ) THEN
-               INFO = -6
-            ELSE IF( .NOT.( LSORT .OR. LSAME( SORT, 'U' ) ) ) THEN
-               INFO = -7
-            END IF
-         END IF
-         IF( INFO.EQ.0 .AND. .NOT.JOBX ) THEN
-            IF( .NOT.( NOFACT .OR. LSAME( FACT, 'F' ) ) ) THEN
-               INFO = -8
-            ELSE IF( .NOT.( UPDATE .OR. LSAME( LYAPUN, 'R' ) ) ) THEN
-               INFO = -9
-            END IF
-         END IF
-         IF( INFO.EQ.0 ) THEN
-            IF( N.LT.0 ) THEN
-               INFO = -10
-            ELSE IF( LDA.LT.1 .OR. ( ( JBXA .OR. NOFACT .OR. UPDATE )
-     $         .AND. LDA.LT.N ) ) THEN
-               INFO = -12
-            ELSE IF( LDT.LT.1 .OR. ( .NOT. JOBX .AND. LDT.LT.N ) ) THEN
-               INFO = -14
-            ELSE IF( LDV.LT.1 .OR. ( .NOT. JOBX .AND. LDV.LT.N ) ) THEN
-               INFO = -16
-            ELSE IF( LDG.LT.MAX( 1, N ) ) THEN
-               INFO = -18
-            ELSE IF( LDQ.LT.MAX( 1, N ) ) THEN
-               INFO = -20
-            ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
-               INFO = -22
-            ELSE IF( LDS.LT.1 .OR. ( JBXA .AND. LDS.LT.N2 ) ) THEN
-               INFO = -29
-            ELSE
-               IF( JBXA ) THEN
-                  IF( LDWORK.LT.5 + MAX( 1, 4*NN + 8*N ) )
-     $               INFO = -32
-               ELSE
-                  IF( NOFACT .AND. UPDATE ) THEN
-                     IF( .NOT.DISCR .AND. JOBC ) THEN
-                        LWS = 5*N
-                     ELSE
-                        LWS = 5*N + NN
-                     END IF
-                  ELSE
-                     LWS = 0
-                  END IF
-                  IF( DISCR ) THEN
-                     IF( JOBC ) THEN
-                        LWE = MAX( 3, 2*NN) + NN
-                     ELSE
-                        LWE = MAX( 3, 2*NN) + 2*NN
-                     END IF
-                  ELSE
-                     IF( JOBC ) THEN
-                        LWE = 2*NN
-                     ELSE
-                        LWE = 4*NN
-                     END IF
-                  END IF
-                  IF( UPDATE .OR. JOBC ) THEN
-                     LWN = 0
-                  ELSE
-                     IF( DISCR ) THEN
-                        LWN = 3*N
-                     ELSE
-                        LWN = 2*N
-                     END IF
-                  END IF
-                  IF( LDWORK.LT.5 + MAX( 1, LWS, LWE ) + LWN )
-     $               INFO = -32
-               END IF
-            END IF
-         END IF
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB02RD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( N.EQ.0 ) THEN
-         IF( JOBX )
-     $      SEP = ONE
-         IF( JOBC .OR. JOBA )
-     $      RCOND = ONE
-         IF( JOBE .OR. JOBA )
-     $      FERR  = ZERO
-         DWORK(1) = ONE
-         DWORK(2) = ONE
-         DWORK(3) = ONE
-         IF ( DISCR ) THEN
-            DWORK(4) = ONE
-            DWORK(5) = ONE
-         END IF
-         RETURN
-      END IF
-C
-      IF ( JBXA ) THEN
-C
-C        Compute the solution matrix X.
-C
-C        Initialise the Hamiltonian or symplectic matrix associated with
-C        the problem.
-C        Workspace:  need   0    if DICO = 'C';
-C                           6*N, if DICO = 'D'.
-C
-         CALL SB02RU( DICO, HINV, TRANA, UPLO, N, A, LDA, G, LDG, Q,
-     $                LDQ, S, LDS, IWORK, DWORK, LDWORK, IERR )
-C
-         IF ( IERR.NE.0 ) THEN
-            INFO = 1
-            IF ( DISCR ) THEN
-               DWORK(4) = DWORK(1)
-               DWORK(5) = DWORK(2)
-            END IF
-            RETURN
-         END IF
-C
-         IF ( DISCR ) THEN
-            WRKOPT = 6*N
-            RCONDA = DWORK(1)
-            PIVOTA = DWORK(2)
-         ELSE
-            WRKOPT = 0
-         END IF
-C
-         IF ( LSCAL ) THEN
-C
-C           Scale the Hamiltonian or symplectic matrix S, using the
-C           square roots of the norms of the matrices Q and G.
-C
-            QNORM = SQRT( DLANSY( '1-norm', UPLO, N, Q, LDQ, DWORK ) )
-            GNORM = SQRT( DLANSY( '1-norm', UPLO, N, G, LDG, DWORK ) )
-C
-            LSCL = QNORM.GT.GNORM .AND. GNORM.GT.ZERO
-            IF( LSCL ) THEN
-               CALL DLASCL( 'G', 0, 0, QNORM, GNORM, N, N, S(NP1,1),
-     $                      LDS, IERR )
-               CALL DLASCL( 'G', 0, 0, GNORM, QNORM, N, N, S(1,NP1),
-     $                      LDS, IERR )
-            END IF
-         ELSE
-            LSCL = .FALSE.
-         END IF
-C
-C        Find the ordered Schur factorization of S,  S = U*H*U'.
-C        Workspace:  need   5 + 4*N*N + 6*N;
-C                    prefer larger.
-C
-         IU  = 6
-         IW  = IU + 4*NN
-         LDW = LDWORK - IW + 1
-         IF ( .NOT.DISCR ) THEN
-            IF ( LSORT ) THEN
-               CALL DGEES( 'Vectors', 'Sorted', SB02MV, N2, S, LDS,
-     $                     NROT, WR, WI, DWORK(IU), N2, DWORK(IW), LDW,
-     $                     BWORK, IERR )
-            ELSE
-               CALL DGEES( 'Vectors', 'Sorted', SB02MR, N2, S, LDS,
-     $                     NROT, WR, WI, DWORK(IU), N2, DWORK(IW), LDW,
-     $                     BWORK, IERR )
-            END IF
-         ELSE
-            IF ( LSORT ) THEN
-               CALL DGEES( 'Vectors', 'Sorted', SB02MW, N2, S, LDS,
-     $                     NROT, WR, WI, DWORK(IU), N2, DWORK(IW), LDW,
-     $                     BWORK, IERR )
-            ELSE
-               CALL DGEES( 'Vectors', 'Sorted', SB02MS, N2, S, LDS,
-     $                     NROT, WR, WI, DWORK(IU), N2, DWORK(IW), LDW,
-     $                     BWORK, IERR )
-            END IF
-            IF ( LHINV ) THEN
-               CALL DSWAP( N, WR, 1, WR(NP1), 1 )
-               CALL DSWAP( N, WI, 1, WI(NP1), 1 )
-            END IF
-         END IF
-         IF ( IERR.GT.N2 ) THEN
-            INFO = 3
-         ELSE IF ( IERR.GT.0 ) THEN
-            INFO = 2
-         ELSE IF ( NROT.NE.N ) THEN
-            INFO = 4
-         END IF
-         IF ( INFO.NE.0 ) THEN
-            IF ( DISCR ) THEN
-               DWORK(4) = RCONDA
-               DWORK(5) = PIVOTA
-            END IF
-            RETURN
-         END IF
-C
-         WRKOPT = MAX( WRKOPT, DWORK(IW) + DBLE( IW - 1 ) )
-C
-C        Compute the solution of X*U(1,1) = U(2,1) using
-C        LU factorization and iterative refinement. The (2,1) block of S
-C        is used as a workspace for factoring U(1,1).
-C        Workspace:  need   5 + 4*N*N + 8*N.
-C
-C        First transpose U(2,1) in-situ.
-C
-         DO 20 I = 1, N - 1
-            CALL DSWAP( N-I, DWORK(IU+N+I*(N2+1)-1), N2,
-     $                  DWORK(IU+N+(I-1)*(N2+1)+1), 1 )
-   20    CONTINUE
-C
-         IWR = IW
-         IWC = IWR + N
-         IWF = IWC + N
-         IWB = IWF + N
-         IW  = IWB + N
-C
-         CALL MB02PD( 'Equilibrate', 'Transpose', N, N, DWORK(IU), N2,
-     $                S(NP1,1), LDS, IWORK, EQUED, DWORK(IWR),
-     $                DWORK(IWC), DWORK(IU+N), N2, X, LDX, RCONDU,
-     $                DWORK(IWF), DWORK(IWB), IWORK(NP1), DWORK(IW),
-     $                IERR )
-         IF( JOBX ) THEN
-C
-C           Restore U(2,1) back in-situ.
-C
-            DO 40 I = 1, N - 1
-               CALL DSWAP( N-I, DWORK(IU+N+I*(N2+1)-1), N2,
-     $                     DWORK(IU+N+(I-1)*(N2+1)+1), 1 )
-   40       CONTINUE
-C
-            IF( .NOT.LSAME( EQUED, 'N' ) ) THEN
-C
-C              Undo the equilibration of U(1,1) and U(2,1).
-C
-               ROWEQU = LSAME( EQUED, 'R' ) .OR. LSAME( EQUED, 'B' )
-               COLEQU = LSAME( EQUED, 'C' ) .OR. LSAME( EQUED, 'B' )
-C
-               IF( ROWEQU ) THEN
-C
-                  DO 60 I = 1, N
-                     DWORK(IWR+I-1) = ONE / DWORK(IWR+I-1)
-   60             CONTINUE
-C
-                  CALL MB01SD( 'Row scaling', N, N, DWORK(IU), N2,
-     $                         DWORK(IWR), DWORK(IWC) )
-               END IF
-C
-               IF( COLEQU ) THEN
-C
-                  DO 80 I = 1, N
-                     DWORK(IWC+I-1) = ONE / DWORK(IWC+I-1)
-   80             CONTINUE
-C
-                  CALL MB01SD( 'Column scaling', N, N, DWORK(IU), N2,
-     $                         DWORK(IWR), DWORK(IWC) )
-                  CALL MB01SD( 'Column scaling', N, N, DWORK(IU+N), N2,
-     $                         DWORK(IWR), DWORK(IWC) )
-               END IF
-            END IF
-C
-C           Set S(2,1) to zero.
-C
-            CALL DLASET( 'Full', N, N, ZERO, ZERO, S(NP1,1), LDS )
-         END IF
-C
-         PIVOTU = DWORK(IW)
-C
-         IF ( IERR.GT.0 ) THEN
-C
-C           Singular matrix. Set INFO and DWORK for error return.
-C
-            INFO = 5
-            GO TO 160
-         END IF
-C
-C        Make sure the solution matrix X is symmetric.
-C
-         DO 100 I = 1, N - 1
-            CALL DAXPY( N-I, ONE, X(I,I+1), LDX, X(I+1,I), 1 )
-            CALL DSCAL( N-I, HALF, X(I+1,I), 1 )
-            CALL DCOPY( N-I, X(I+1,I), 1, X(I,I+1), LDX )
-  100    CONTINUE
-C
-         IF( LSCAL ) THEN
-C
-C           Undo scaling for the solution matrix.
-C
-            IF( LSCL )
-     $         CALL DLASCL( 'G', 0, 0, GNORM, QNORM, N, N, X, LDX,
-     $                      IERR )
-         END IF
-      END IF
-C
-      IF ( .NOT.JOBX ) THEN
-         IF ( .NOT.JOBA )
-     $      WRKOPT = 0
-C
-C        Estimate the conditioning and compute an error bound on the
-C        solution of the algebraic Riccati equation.
-C
-         IW = 6
-         LOFACT = FACT
-         IF ( NOFACT .AND. .NOT.UPDATE ) THEN
-C
-C           Compute Ac and its Schur factorization.
-C
-            IF ( DISCR ) THEN
-               CALL DLASET( 'Full', N, N, ZERO, ONE, DWORK(IW), N )
-               CALL DSYMM(  'Left', UPLO, N, N, ONE, G, LDG, X, LDX,
-     $                      ONE, DWORK(IW), N )
-               IF ( NOTRNA ) THEN
-C
-C                 Compute Ac = inv(I_n + G*X)*A.
-C
-                  CALL DLACPY( 'Full', N, N, A, LDA, T, LDT )
-                  CALL DGESV( N, N, DWORK(IW), N, IWORK, T, LDT, IERR )
-               ELSE
-C
-C                 Compute Ac = A*inv(I_n + X*G).
-C
-                  CALL MA02AD( 'Full', N, N, A, LDA, T, LDT )
-                  CALL DGESV( N, N, DWORK(IW), N, IWORK, T, LDT, IERR )
-                  DO 120 I = 2, N
-                     CALL DSWAP( I-1, T(1,I), 1, T(I,1), LDT )
-  120             CONTINUE
-               END IF
-C
-            ELSE
-C
-               CALL DLACPY( 'Full', N, N, A, LDA, T, LDT )
-               IF ( NOTRNA ) THEN
-C
-C                 Compute Ac = A - G*X.
-C
-                  CALL DSYMM( 'Left', UPLO, N, N, -ONE, G, LDG, X, LDX,
-     $                        ONE, T, LDT )
-               ELSE
-C
-C                 Compute Ac = A - X*G.
-C
-                  CALL DSYMM( 'Right', UPLO, N, N, -ONE, G, LDG, X, LDX,
-     $                        ONE, T, LDT )
-               END IF
-            END IF
-C
-C           Compute the Schur factorization of Ac, Ac = V*T*V'.
-C           Workspace:  need   5 + 5*N.
-C                       prefer larger.
-C
-            IWR = IW
-            IWI = IWR + N
-            IW  = IWI + N
-            LDW = LDWORK - IW + 1
-C
-            CALL DGEES( 'Vectors', 'Not ordered', SB02MS, N, T, LDT,
-     $                  NROT, DWORK(IWR), DWORK(IWI), V, LDV, DWORK(IW),
-     $                  LDW, BWORK, IERR )
-C
-            IF( IERR.NE.0 ) THEN
-               INFO = 6
-               GO TO 160
-            END IF
-C
-            WRKOPT = MAX( WRKOPT, DWORK(IW) + DBLE( IW - 1 ) )
-            LOFACT = 'F'
-            IW = 6
-         END IF
-C
-         IF ( .NOT.UPDATE ) THEN
-C
-C           Update G, Q, and X using the orthogonal matrix V.
-C
-            TRANAT = 'T'
-C
-C           Save the diagonal elements of G and Q.
-C
-            CALL DCOPY( N, G, LDG+1, DWORK(IW), 1 )
-            CALL DCOPY( N, Q, LDQ+1, DWORK(IW+N), 1 )
-            IW = IW + N2
-C
-            IF ( JOBA )
-     $         CALL DLACPY( 'Full', N, N, X, LDX, S(NP1,1), LDS )
-            CALL MB01RU( UPLO, TRANAT, N, N, ZERO, ONE, X, LDX, V, LDV,
-     $                   X, LDX, DWORK(IW), NN, IERR )
-            CALL DSCAL( N, HALF, X, LDX+1 )
-            CALL MA02ED( UPLO, N, X, LDX )
-            IF( .NOT.DISCR ) THEN
-               CALL MA02ED( UPLO, N, G, LDG )
-               CALL MA02ED( UPLO, N, Q, LDQ )
-            END IF
-            CALL MB01RU( UPLO, TRANAT, N, N, ZERO, ONE, G, LDG, V, LDV,
-     $                   G, LDG, DWORK(IW), NN, IERR )
-            CALL DSCAL( N, HALF, G, LDG+1 )
-            CALL MB01RU( UPLO, TRANAT, N, N, ZERO, ONE, Q, LDQ, V, LDV,
-     $                   Q, LDQ, DWORK(IW), NN, IERR )
-            CALL DSCAL( N, HALF, Q, LDQ+1 )
-         END IF
-C
-C        Estimate the conditioning and/or the error bound.
-C        Workspace: 5 + MAX(1,LWS,LWE) + LWN, where
-C
-C           LWS = 0,       if FACT = 'F' or  LYAPUN = 'R';
-C               = 5*N,     if FACT = 'N' and LYAPUN = 'O' and DICO = 'C'
-C                                                         and JOB = 'C';
-C               = 5*N+N*N, if FACT = 'N' and LYAPUN = 'O' and DICO = 'C'
-C                                          and (JOB = 'E' or JOB = 'A');
-C               = 5*N+N*N, if FACT = 'N' and LYAPUN = 'O' and
-C                                                         DICO = 'D';
-C           LWE = 2*N*N,                if DICO = 'C' and  JOB = 'C';
-C               = 4*N*N,                if DICO = 'C' and (JOB = 'E' or
-C                                                          JOB = 'A');
-C               = MAX(3,2*N*N) + N*N,   if DICO = 'D' and  JOB = 'C';
-C               = MAX(3,2*N*N) + 2*N*N, if DICO = 'D' and (JOB = 'E' or
-C                                                          JOB = 'A');
-C           LWN = 0,   if LYAPUN = 'O' or   JOB = 'C';
-C               = 2*N, if LYAPUN = 'R' and DICO = 'C' and (JOB = 'E' or
-C                                                          JOB = 'A');
-C               = 3*N, if LYAPUN = 'R' and DICO = 'D' and (JOB = 'E' or
-C                                                          JOB = 'A').
-C
-         LDW = LDWORK - IW + 1
-         IF ( JOBA ) THEN
-            JOBS = 'B'
-         ELSE
-            JOBS = JOB
-         END IF
-C
-         IF ( DISCR ) THEN
-            CALL SB02SD( JOBS, LOFACT, TRANA, UPLO, LYAPUN, N, A, LDA,
-     $                   T, LDT, V, LDV, G, LDG, Q, LDQ, X, LDX, SEP,
-     $                   RCOND, FERR, IWORK, DWORK(IW), LDW, IERR )
-         ELSE
-            CALL SB02QD( JOBS, LOFACT, TRANA, UPLO, LYAPUN, N, A, LDA,
-     $                   T, LDT, V, LDV, G, LDG, Q, LDQ, X, LDX, SEP,
-     $                   RCOND, FERR, IWORK, DWORK(IW), LDW, IERR )
-         END IF
-C
-         WRKOPT = MAX( WRKOPT, DWORK(IW) + DBLE( IW - 1 ) )
-         IF( IERR.EQ.NP1 ) THEN
-            INFO = 7
-         ELSE IF( IERR.GT.0 ) THEN
-            INFO = 6
-            GO TO 160
-         END IF
-C
-         IF ( .NOT.UPDATE ) THEN
-C
-C           Restore X, G, and Q and set S(2,1) to zero, if needed.
-C
-            IF ( JOBA ) THEN
-               CALL DLACPY( 'Full', N, N, S(NP1,1), LDS, X, LDX )
-               CALL DLASET( 'Full', N, N, ZERO, ZERO, S(NP1,1), LDS )
-            ELSE
-               CALL MB01RU( UPLO, TRANA, N, N, ZERO, ONE, X, LDX, V,
-     $                      LDV, X, LDX, DWORK(IW), NN, IERR )
-               CALL DSCAL( N, HALF, X, LDX+1 )
-               CALL MA02ED( UPLO, N, X, LDX )
-            END IF
-            IF ( LUPLO ) THEN
-               LOUP = 'L'
-            ELSE
-               LOUP = 'U'
-            END IF
-C
-            IW = 6
-            CALL DCOPY( N, DWORK(IW), 1, G, LDG+1 )
-            CALL MA02ED( LOUP, N, G, LDG )
-            CALL DCOPY( N, DWORK(IW+N), 1, Q, LDQ+1 )
-            CALL MA02ED( LOUP, N, Q, LDQ )
-         END IF
-C
-      END IF
-C
-C     Set the optimal workspace and other details.
-C
-      DWORK(1) = WRKOPT
-  160 CONTINUE
-      IF( JBXA ) THEN
-         DWORK(2) = RCONDU
-         DWORK(3) = PIVOTU
-         IF ( DISCR ) THEN
-            DWORK(4) = RCONDA
-            DWORK(5) = PIVOTA
-         END IF
-         IF( JOBX ) THEN
-            IF ( LSCL ) THEN
-               SEP = QNORM / GNORM
-            ELSE
-               SEP = ONE
-            END IF
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of SB02RD ***
-      END
--- a/extra/control-devel/src/SB02RU.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,508 +0,0 @@
-      SUBROUTINE SB02RU( DICO, HINV, TRANA, UPLO, N, A, LDA, G, LDG, Q,
-     $                   LDQ, S, LDS, 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 2n-by-2n Hamiltonian or symplectic matrix S
-C     associated to the linear-quadratic optimization problem, used to
-C     solve the continuous- or discrete-time algebraic Riccati equation,
-C     respectively.
-C
-C     For a continuous-time problem, S is defined by
-C
-C             ( op(A)   -G    )
-C         S = (               ),                                     (1)
-C             (  -Q   -op(A)' )
-C
-C     and for a discrete-time problem by
-C
-C                     -1              -1
-C             (  op(A)           op(A)  *G       )
-C         S = (        -1                   -1   ),                  (2)
-C             ( Q*op(A)     op(A)' + Q*op(A)  *G )
-C
-C     or
-C                              -T             -T
-C             ( op(A) + G*op(A)  *Q   -G*op(A)   )
-C         S = (           -T                 -T  ),                  (3)
-C             (     -op(A)  *Q          op(A)    )
-C
-C     where op(A) = A or A' (A**T), A, G, and Q are n-by-n matrices,
-C     with G and Q symmetric. Matrix A must be nonsingular in the
-C     discrete-time case.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the system as follows:
-C             = 'C':  Continuous-time system;
-C             = 'D':  Discrete-time system.
-C
-C     HINV    CHARACTER*1
-C             If DICO = 'D', specifies which of the matrices (2) or (3)
-C             is constructed, as follows:
-C             = 'D':  The matrix S in (2) is constructed;
-C             = 'I':  The (inverse) matrix S in (3) is constructed.
-C             HINV is not referenced if DICO = 'C'.
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     UPLO    CHARACTER*1
-C             Specifies which triangle of the matrices G and Q is
-C             stored, as follows:
-C             = 'U':  Upper triangle is stored;
-C             = 'L':  Lower triangle is stored.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A, G, and Q.  N >= 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             matrix A.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= MAX(1,N).
-C
-C     G       (input/output) DOUBLE PRECISION array, dimension (LDG,N)
-C             On entry, the leading N-by-N upper triangular part (if
-C             UPLO = 'U') or lower triangular part (if UPLO = 'L') of
-C             this array must contain the upper triangular part or lower
-C             triangular part, respectively, of the symmetric matrix G.
-C             On exit, if DICO = 'D', the leading N-by-N part of this
-C             array contains the symmetric matrix G fully stored.
-C             If DICO = 'C', this array is not modified on exit, and the
-C             strictly lower triangular part (if UPLO = 'U') or strictly
-C             upper triangular part (if UPLO = 'L') is not referenced.
-C
-C     LDG     INTEGER
-C             The leading dimension of the array G.  LDG >= MAX(1,N).
-C
-C     Q       (input/output) DOUBLE PRECISION array, dimension (LDQ,N)
-C             On entry, the leading N-by-N upper triangular part (if
-C             UPLO = 'U') or lower triangular part (if UPLO = 'L') of
-C             this array must contain the upper triangular part or lower
-C             triangular part, respectively, of the symmetric matrix Q.
-C             On exit, if DICO = 'D', the leading N-by-N part of this
-C             array contains the symmetric matrix Q fully stored.
-C             If DICO = 'C', this array is not modified on exit, and the
-C             strictly lower triangular part (if UPLO = 'U') or strictly
-C             upper triangular part (if UPLO = 'L') is not referenced.
-C
-C     LDQ     INTEGER
-C             The leading dimension of the array Q.  LDQ >= MAX(1,N).
-C
-C     S       (output) DOUBLE PRECISION array, dimension (LDS,2*N)
-C             If INFO = 0, the leading 2N-by-2N part of this array
-C             contains the Hamiltonian or symplectic matrix of the
-C             problem.
-C
-C     LDS     INTEGER
-C             The leading dimension of the array S.  LDS >= MAX(1,2*N).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK), where
-C             LIWORK >= 0,   if DICO = 'C';
-C             LIWORK >= 2*N, if DICO = 'D'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if DICO = 'D', DWORK(1) returns the reciprocal
-C             condition number  RCOND  of the given matrix  A,  and
-C             DWORK(2) returns the reciprocal pivot growth factor
-C             norm(A)/norm(U) (see SLICOT Library routine MB02PD).
-C             If DWORK(2) is much less than 1, then the computed  S
-C             and  RCOND  could be unreliable. If 0 < INFO <= N, then
-C             DWORK(2) contains the reciprocal pivot growth factor for
-C             the leading INFO columns of  A.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 0,          if DICO = 'C';
-C             LDWORK >= MAX(2,6*N), if DICO = 'D'.
-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             = i:  if the leading i-by-i (1 <= i <= N) upper triangular
-C                   submatrix of A is singular in discrete-time case;
-C             = N+1:  if matrix A is numerically singular in discrete-
-C                   time case.
-C
-C     METHOD
-C
-C     For a continuous-time problem, the 2n-by-2n Hamiltonian matrix (1)
-C     is constructed.
-C     For a discrete-time problem, the 2n-by-2n symplectic matrix (2) or
-C     (3) - the inverse of the matrix in (2) - is constructed.
-C
-C     NUMERICAL ASPECTS
-C
-C     The discrete-time case needs the inverse of the matrix A, hence
-C     the routine should not be used when A is ill-conditioned.
-C                               3
-C     The algorithm requires 0(n ) floating point operations in the
-C     discrete-time case.
-C
-C     FURTHER COMMENTS
-C
-C     This routine is a functionally extended and with improved accuracy
-C     version of the SLICOT Library routine SB02MU. Transposed problems
-C     can be dealt with as well. The LU factorization of  op(A)  (with
-C     no equilibration) and iterative refinement are used for solving
-C     the various linear algebraic systems involved.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 1999.
-C
-C     REVISIONS
-C
-C     -
-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, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, HINV, TRANA, UPLO
-      INTEGER           INFO, LDA, LDG, LDQ, LDS, LDWORK, N
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), DWORK(*), G(LDG,*), Q(LDQ,*),
-     $                  S(LDS,*)
-C     .. Local Scalars ..
-      CHARACTER         EQUED, TRANAT
-      LOGICAL           DISCR, LHINV, LUPLO, NOTRNA
-      INTEGER           I, J, N2, NJ, NP1
-      DOUBLE PRECISION  PIVOTG, RCOND, RCONDA, TEMP
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DCOPY, DGEMM, DLACPY, DLASET, DSWAP, MA02AD,
-     $                  MA02ED, MB02PD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX
-C     .. Executable Statements ..
-C
-      N2 = N + N
-      INFO = 0
-      DISCR  = LSAME( DICO,  'D' )
-      LUPLO  = LSAME( UPLO,  'U' )
-      NOTRNA = LSAME( TRANA, 'N' )
-      IF( DISCR )
-     $   LHINV = LSAME( HINV, 'D' )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.DISCR .AND. .NOT.LSAME( DICO, 'C' ) ) THEN
-         INFO = -1
-      ELSE IF( DISCR ) THEN
-         IF( .NOT.LHINV .AND. .NOT.LSAME( HINV, 'I' ) )
-     $      INFO = -2
-      ELSE IF( INFO.EQ.0 ) THEN
-         IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'T' )
-     $                   .AND. .NOT.LSAME( TRANA, 'C' ) ) THEN
-            INFO = -3
-         ELSE IF( .NOT.LUPLO .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
-            INFO = -4
-         ELSE IF( N.LT.0 ) THEN
-            INFO = -5
-         ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-            INFO = -7
-         ELSE IF( LDG.LT.MAX( 1, N ) ) THEN
-            INFO = -9
-         ELSE IF( LDQ.LT.MAX( 1, N ) ) THEN
-            INFO = -11
-         ELSE IF( LDS.LT.MAX( 1, N2 ) ) THEN
-            INFO = -13
-         ELSE IF( ( LDWORK.LT.0 ) .OR.
-     $            ( DISCR .AND. LDWORK.LT.MAX( 2, 6*N ) ) ) THEN
-            INFO = -16
-         END IF
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB02RU', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( N.EQ.0 ) THEN
-         IF ( DISCR ) THEN
-            DWORK(1) = ONE
-            DWORK(2) = ONE
-         END IF
-         RETURN
-      END IF
-C
-C     The code tries to exploit data locality as much as possible,
-C     assuming that LDS is greater than LDA, LDQ, and/or LDG.
-C
-      IF ( .NOT.DISCR ) THEN
-C
-C        Continuous-time case: Construct Hamiltonian matrix column-wise.
-C
-C        Copy op(A) in S(1:N,1:N), and construct full Q
-C        in S(N+1:2*N,1:N) and change the sign.
-C
-         DO 100 J = 1, N
-            IF ( NOTRNA ) THEN
-               CALL DCOPY( N, A(1,J), 1, S(1,J), 1 )
-            ELSE
-               CALL DCOPY( N, A(J,1), LDA, S(1,J), 1 )
-            END IF
-C
-            IF ( LUPLO ) THEN
-C
-               DO 20 I = 1, J
-                  S(N+I,J) = -Q(I,J)
-   20          CONTINUE
-C
-               DO 40 I = J + 1, N
-                  S(N+I,J) = -Q(J,I)
-   40          CONTINUE
-C
-            ELSE
-C
-               DO 60 I = 1, J - 1
-                  S(N+I,J) = -Q(J,I)
-   60          CONTINUE
-C
-               DO 80 I = J, N
-                  S(N+I,J) = -Q(I,J)
-   80          CONTINUE
-C
-            END IF
-  100    CONTINUE
-C
-C        Construct full G in S(1:N,N+1:2*N) and change the sign, and
-C        construct -op(A)' in S(N+1:2*N,N+1:2*N).
-C
-         DO 240 J = 1, N
-            NJ = N + J
-            IF ( LUPLO ) THEN
-C
-               DO 120 I = 1, J
-                  S(I,NJ) = -G(I,J)
-  120          CONTINUE
-C
-               DO 140 I = J + 1, N
-                  S(I,NJ) = -G(J,I)
-  140          CONTINUE
-C
-            ELSE
-C
-               DO 160 I = 1, J - 1
-                  S(I,NJ) = -G(J,I)
-  160          CONTINUE
-C
-               DO 180 I = J, N
-                  S(I,NJ) = -G(I,J)
-  180          CONTINUE
-C
-            END IF
-C
-            IF ( NOTRNA ) THEN
-C
-               DO 200 I = 1, N
-                  S(N+I,NJ) = -A(J,I)
-  200          CONTINUE
-C
-            ELSE
-C
-               DO 220 I = 1, N
-                  S(N+I,NJ) = -A(I,J)
-  220          CONTINUE
-C
-            END IF
-  240    CONTINUE
-C
-      ELSE
-C
-C        Discrete-time case: Construct the symplectic matrix (2) or (3).
-C
-C        Fill in the remaining triangles of the symmetric matrices Q
-C        and G.
-C
-         CALL MA02ED( UPLO, N, Q, LDQ )
-         CALL MA02ED( UPLO, N, G, LDG )
-C
-C        Prepare the construction of S in (2) or (3).
-C
-         NP1 = N + 1
-         IF ( NOTRNA ) THEN
-            TRANAT = 'T'
-         ELSE
-            TRANAT = 'N'
-         END IF
-C
-C        Solve  op(A)'*X = Q  in  S(N+1:2*N,1:N),  using the LU
-C        factorization of  op(A),  obtained in  S(1:N,1:N),  and
-C        iterative refinement. No equilibration of  A  is used.
-C        Workspace:  6*N.
-C
-         CALL MB02PD( 'No equilibration', TRANAT, N, N, A, LDA, S,
-     $                LDS, IWORK, EQUED, DWORK, DWORK, Q, LDQ,
-     $                S(NP1,1), LDS, RCOND, DWORK, DWORK(NP1),
-     $                IWORK(NP1), DWORK(N2+1), INFO )
-C
-C        Return if the matrix is exactly singular or singular to
-C        working precision.
-C
-         IF( INFO.GT.0 ) THEN
-            DWORK(1) = RCOND
-            DWORK(2) = DWORK(N2+1)
-            RETURN
-         END IF
-C
-         RCONDA = RCOND
-         PIVOTG = DWORK(N2+1)
-C
-         IF ( LHINV ) THEN
-C
-C           Complete the construction of S in (2).
-C
-C           Transpose  X  in-situ.
-C
-            DO 260 J = 1, N - 1
-               CALL DSWAP( N-J, S(NP1+J,J), 1, S(N+J,J+1), LDS )
-  260       CONTINUE
-C
-C           Solve  op(A)*X = I_n  in  S(N+1:2*N,N+1:2*N),  using the LU
-C           factorization of  op(A),  computed in  S(1:N,1:N),  and
-C           iterative refinement.
-C
-            CALL DLASET( 'Full', N, N, ZERO, ONE, S(1,NP1), LDS )
-            CALL MB02PD( 'Factored', TRANA, N, N, A, LDA, S, LDS, IWORK,
-     $                   EQUED, DWORK, DWORK, S(1,NP1), LDS, S(NP1,NP1),
-     $                   LDS, RCOND, DWORK, DWORK(NP1), IWORK(NP1),
-     $                   DWORK(N2+1), INFO )
-C
-C           Solve  op(A)*X = G  in  S(1:N,N+1:2*N),  using the LU
-C           factorization of  op(A),  computed in  S(1:N,1:N),  and
-C           iterative refinement.
-C
-            CALL MB02PD( 'Factored', TRANA, N, N, A, LDA, S, LDS, IWORK,
-     $                   EQUED, DWORK, DWORK, G, LDG, S(1,NP1), LDS,
-     $                   RCOND, DWORK, DWORK(NP1), IWORK(NP1),
-     $                   DWORK(N2+1), INFO )
-C
-C                      -1
-C           Copy  op(A)    from  S(N+1:2*N,N+1:2*N)  in  S(1:N,1:N).
-C
-            CALL DLACPY( 'Full', N, N, S(NP1,NP1), LDS, S, LDS )
-C
-C                                    -1
-C           Compute  op(A)' + Q*op(A)  *G  in  S(N+1:2*N,N+1:2*N).
-C
-            IF ( NOTRNA ) THEN
-               CALL MA02AD( 'Full', N, N, A, LDA, S(NP1,NP1), LDS )
-            ELSE
-               CALL DLACPY( 'Full', N, N, A, LDA, S(NP1,NP1), LDS )
-            END IF
-            CALL DGEMM( 'No transpose', 'No transpose', N, N, N, ONE,
-     $                  Q, LDQ, S(1,NP1), LDS, ONE, S(NP1,NP1), LDS )
-C
-         ELSE
-C
-C           Complete the construction of S in (3).
-C
-C           Change the sign of  X.
-C
-            DO 300 J = 1, N
-C
-               DO 280 I = NP1, N2
-                  S(I,J) = -S(I,J)
-  280          CONTINUE
-C
-  300       CONTINUE
-C
-C           Solve  op(A)'*X = I_n  in  S(N+1:2*N,N+1:2*N),  using the LU
-C           factorization of  op(A),  computed in  S(1:N,1:N),  and
-C           iterative refinement.
-C
-            CALL DLASET( 'Full', N, N, ZERO, ONE, S(1,NP1), LDS )
-            CALL MB02PD( 'Factored', TRANAT, N, N, A, LDA, S, LDS,
-     $                   IWORK, EQUED, DWORK, DWORK, S(1,NP1), LDS,
-     $                   S(NP1,NP1), LDS, RCOND, DWORK, DWORK(NP1),
-     $                   IWORK(NP1), DWORK(N2+1), INFO )
-C
-C           Solve  op(A)*X' = -G  in  S(1:N,N+1:2*N),  using the LU
-C           factorization of  op(A),  obtained in  S(1:N,1:N),  and
-C           iterative refinement.
-C
-            CALL MB02PD( 'Factored', TRANA, N, N, A, LDA, S, LDS, IWORK,
-     $                   EQUED, DWORK, DWORK, G, LDG, S(1,NP1), LDS,
-     $                   RCOND, DWORK, DWORK(NP1), IWORK(NP1),
-     $                   DWORK(N2+1), INFO )
-C
-C           Change the sign of  X  and transpose it in-situ.
-C
-            DO 340 J = NP1, N2
-C
-               DO 320 I = 1, N
-                  TEMP   = -S(I,J)
-                  S(I,J) = -S(J-N,I+N)
-                  S(J-N,I+N) = TEMP
-  320          CONTINUE
-C
-  340       CONTINUE
-C                                   -T
-C           Compute  op(A) + G*op(A)  *Q  in  S(1:N,1:N).
-C
-            IF ( NOTRNA ) THEN
-               CALL DLACPY( 'Full', N, N, A, LDA, S, LDS )
-            ELSE
-               CALL MA02AD( 'Full', N, N, A, LDA, S, LDS )
-            END IF
-            CALL DGEMM( 'No transpose', 'No transpose', N, N, N, -ONE,
-     $                  G, LDG, S(NP1,1), LDS, ONE, S, LDS )
-C
-         END IF
-         DWORK(1) = RCONDA
-         DWORK(2) = PIVOTG
-      END IF
-      RETURN
-C
-C *** Last line of SB02RU ***
-      END
--- a/extra/control-devel/src/SB02SD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,859 +0,0 @@
-      SUBROUTINE SB02SD( JOB, FACT, TRANA, UPLO, LYAPUN, N, A, LDA, T,
-     $                   LDT, U, LDU, G, LDG, Q, LDQ, X, LDX, SEPD,
-     $                   RCOND, FERR, 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 estimate the conditioning and compute an error bound on the
-C     solution of the real discrete-time matrix algebraic Riccati
-C     equation (see FURTHER COMMENTS)
-C                                 -1
-C         X = op(A)'*X*(I_n + G*X)  *op(A) + Q,                      (1)
-C
-C     where op(A) = A or A' (A**T) and Q, G are symmetric (Q = Q**T,
-C     G = G**T). The matrices A, Q and G are N-by-N and the solution X
-C     is N-by-N.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies the computation to be performed, as follows:
-C             = 'C':  Compute the reciprocal condition number only;
-C             = 'E':  Compute the error bound only;
-C             = 'B':  Compute both the reciprocal condition number and
-C                     the error bound.
-C
-C     FACT    CHARACTER*1
-C             Specifies whether or not the real Schur factorization of
-C             the matrix Ac = inv(I_n + G*X)*A (if TRANA = 'N'), or
-C             Ac = A*inv(I_n + X*G) (if TRANA = 'T' or 'C'), is supplied
-C             on entry, as follows:
-C             = 'F':  On entry, T and U (if LYAPUN = 'O') contain the
-C                     factors from the real Schur factorization of the
-C                     matrix Ac;
-C             = 'N':  The Schur factorization of Ac will be computed
-C                     and the factors will be stored in T and U (if
-C                     LYAPUN = 'O').
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     UPLO    CHARACTER*1
-C             Specifies which part of the symmetric matrices Q and G is
-C             to be used, as follows:
-C             = 'U':  Upper triangular part;
-C             = 'L':  Lower triangular part.
-C
-C     LYAPUN  CHARACTER*1
-C             Specifies whether or not the original Lyapunov equations
-C             should be solved in the iterative estimation process,
-C             as follows:
-C             = 'O':  Solve the original Lyapunov equations, updating
-C                     the right-hand sides and solutions with the
-C                     matrix U, e.g., RHS <-- U'*RHS*U;
-C             = 'R':  Solve reduced Lyapunov equations only, without
-C                     updating the right-hand sides and solutions.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A, X, Q, and G.  N >= 0.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,N)
-C             If FACT = 'N' or LYAPUN = 'O', the leading N-by-N part of
-C             this array must contain the matrix A.
-C             If FACT = 'F' and LYAPUN = 'R', A is not referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.
-C             LDA >= max(1,N), if FACT = 'N' or  LYAPUN = 'O';
-C             LDA >= 1,        if FACT = 'F' and LYAPUN = 'R'.
-C
-C     T       (input or output) DOUBLE PRECISION array, dimension
-C             (LDT,N)
-C             If FACT = 'F', then T is an input argument and on entry,
-C             the leading N-by-N upper Hessenberg part of this array
-C             must contain the upper quasi-triangular matrix T in Schur
-C             canonical form from a Schur factorization of Ac (see
-C             argument FACT).
-C             If FACT = 'N', then T is an output argument and on exit,
-C             if INFO = 0 or INFO = N+1, the leading N-by-N upper
-C             Hessenberg part of this array contains the upper quasi-
-C             triangular matrix T in Schur canonical form from a Schur
-C             factorization of Ac (see argument FACT).
-C
-C     LDT     INTEGER
-C             The leading dimension of the array T.  LDT >= max(1,N).
-C
-C     U       (input or output) DOUBLE PRECISION array, dimension
-C             (LDU,N)
-C             If LYAPUN = 'O' and FACT = 'F', then U is an input
-C             argument and on entry, the leading N-by-N part of this
-C             array must contain the orthogonal matrix U from a real
-C             Schur factorization of Ac (see argument FACT).
-C             If LYAPUN = 'O' and FACT = 'N', then U is an output
-C             argument and on exit, if INFO = 0 or INFO = N+1, it
-C             contains the orthogonal N-by-N matrix from a real Schur
-C             factorization of Ac (see argument FACT).
-C             If LYAPUN = 'R', the array U is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of the array U.
-C             LDU >= 1,        if LYAPUN = 'R';
-C             LDU >= MAX(1,N), if LYAPUN = 'O'.
-C
-C     G       (input) DOUBLE PRECISION array, dimension (LDG,N)
-C             If UPLO = 'U', the leading N-by-N upper triangular part of
-C             this array must contain the upper triangular part of the
-C             matrix G.
-C             If UPLO = 'L', the leading N-by-N lower triangular part of
-C             this array must contain the lower triangular part of the
-C             matrix G.                     _
-C             Matrix G should correspond to G in the "reduced" Riccati
-C             equation (with matrix T, instead of A), if LYAPUN = 'R'.
-C             See METHOD.
-C
-C     LDG     INTEGER
-C             The leading dimension of the array G.  LDG >= max(1,N).
-C
-C     Q       (input) DOUBLE PRECISION array, dimension (LDQ,N)
-C             If UPLO = 'U', the leading N-by-N upper triangular part of
-C             this array must contain the upper triangular part of the
-C             matrix Q.
-C             If UPLO = 'L', the leading N-by-N lower triangular part of
-C             this array must contain the lower triangular part of the
-C             matrix Q.                     _
-C             Matrix Q should correspond to Q in the "reduced" Riccati
-C             equation (with matrix T, instead of A), if LYAPUN = 'R'.
-C             See METHOD.
-C
-C     LDQ     INTEGER
-C             The leading dimension of the array Q.  LDQ >= max(1,N).
-C
-C     X       (input) DOUBLE PRECISION array, dimension (LDX,N)
-C             The leading N-by-N part of this array must contain the
-C             symmetric solution matrix of the original Riccati
-C             equation (with matrix A), if LYAPUN = 'O', or of the
-C             "reduced" Riccati equation (with matrix T), if
-C             LYAPUN = 'R'. See METHOD.
-C
-C     LDX     INTEGER
-C             The leading dimension of the array X.  LDX >= max(1,N).
-C
-C     SEPD    (output) DOUBLE PRECISION
-C             If JOB = 'C' or JOB = 'B', the estimated quantity
-C             sepd(op(Ac),op(Ac)').
-C             If N = 0, or X = 0, or JOB = 'E', SEPD is not referenced.
-C
-C     RCOND   (output) DOUBLE PRECISION
-C             If JOB = 'C' or JOB = 'B', an estimate of the reciprocal
-C             condition number of the discrete-time Riccati equation.
-C             If N = 0 or X = 0, RCOND is set to 1 or 0, respectively.
-C             If JOB = 'E', RCOND is not referenced.
-C
-C     FERR    (output) DOUBLE PRECISION
-C             If JOB = 'E' or JOB = 'B', an estimated forward error
-C             bound for the solution X. If XTRUE is the true solution,
-C             FERR bounds the magnitude of the largest entry in
-C             (X - XTRUE) divided by the magnitude of the largest entry
-C             in X.
-C             If N = 0 or X = 0, FERR is set to 0.
-C             If JOB = 'C', FERR is not referenced.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N*N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0 or INFO = N+1, DWORK(1) returns the
-C             optimal value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The dimension of the array DWORK.
-C             Let LWA = N*N, if LYAPUN = 'O';
-C                 LWA = 0,   otherwise,
-C             and LWN = N,   if LYAPUN = 'R' and JOB = 'E' or 'B';
-C                 LWN = 0,   otherwise.
-C             If FACT = 'N', then
-C                LDWORK  = MAX(LWA + 5*N, MAX(3,2*N*N) + N*N),
-C                                                 if JOB = 'C';
-C                LDWORK  = MAX(LWA + 5*N, MAX(3,2*N*N) + 2*N*N + LWN),
-C                                                 if JOB = 'E' or 'B'.
-C             If FACT = 'F', then
-C                LDWORK  = MAX(3,2*N*N) + N*N,    if JOB = 'C';
-C                LDWORK  = MAX(3,2*N*N) + 2*N*N + LWN,
-C                                                 if JOB = 'E' or 'B'.
-C             For good performance, LDWORK must generally 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             > 0:  if INFO = i, i <= N, the QR algorithm failed to
-C                   complete the reduction of the matrix Ac to Schur
-C                   canonical form (see LAPACK Library routine DGEES);
-C                   on exit, the matrix T(i+1:N,i+1:N) contains the
-C                   partially converged Schur form, and DWORK(i+1:N) and
-C                   DWORK(N+i+1:2*N) contain the real and imaginary
-C                   parts, respectively, of the converged eigenvalues;
-C                   this error is unlikely to appear;
-C             = N+1:  if T has almost reciprocal eigenvalues; perturbed
-C                   values were used to solve Lyapunov equations, but
-C                   the matrix T, if given (for FACT = 'F'), is
-C                   unchanged.
-C
-C     METHOD
-C
-C     The condition number of the Riccati equation is estimated as
-C
-C     cond = ( norm(Theta)*norm(A) + norm(inv(Omega))*norm(Q) +
-C                 norm(Pi)*norm(G) ) / norm(X),
-C
-C     where Omega, Theta and Pi are linear operators defined by
-C
-C     Omega(W) = op(Ac)'*W*op(Ac) - W,
-C     Theta(W) = inv(Omega(op(W)'*X*op(Ac) + op(Ac)'X*op(W))),
-C        Pi(W) = inv(Omega(op(Ac)'*X*W*X*op(Ac))),
-C
-C     and Ac = inv(I_n + G*X)*A (if TRANA = 'N'), or
-C         Ac = A*inv(I_n + X*G) (if TRANA = 'T' or 'C').
-C
-C     Note that the Riccati equation (1) is equivalent to
-C
-C         X = op(Ac)'*X*op(Ac) + op(Ac)'*X*G*X*op(Ac) + Q,           (2)
-C
-C     and to
-C         _          _                _ _ _         _
-C         X = op(T)'*X*op(T) + op(T)'*X*G*X*op(T) + Q,               (3)
-C           _           _               _
-C     where X = U'*X*U, Q = U'*Q*U, and G = U'*G*U, with U the
-C     orthogonal matrix reducing Ac to a real Schur form, T = U'*Ac*U.
-C
-C     The routine estimates the quantities
-C
-C     sepd(op(Ac),op(Ac)') = 1 / norm(inv(Omega)),
-C
-C     norm(Theta) and norm(Pi) using 1-norm condition estimator.
-C
-C     The forward error bound is estimated using a practical error bound
-C     similar to the one proposed in [2].
-C
-C     REFERENCES
-C
-C     [1] Ghavimi, A.R. and Laub, A.J.
-C         Backward error, sensitivity, and refinement of computed
-C         solutions of algebraic Riccati equations.
-C         Numerical Linear Algebra with Applications, vol. 2, pp. 29-49,
-C         1995.
-C
-C     [2] Higham, N.J.
-C         Perturbation theory and backward error for AX-XB=C.
-C         BIT, vol. 33, pp. 124-136, 1993.
-C
-C     [3] Petkov, P.Hr., Konstantinov, M.M., and Mehrmann, V.
-C         DGRSVX and DMSRIC: Fortran 77 subroutines for solving
-C         continuous-time matrix algebraic Riccati equations with
-C         condition and accuracy estimates.
-C         Preprint SFB393/98-16, Fak. f. Mathematik, Tech. Univ.
-C         Chemnitz, May 1998.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations.
-C     The accuracy of the estimates obtained depends on the solution
-C     accuracy and on the properties of the 1-norm estimator.
-C
-C     FURTHER COMMENTS
-C
-C     The option LYAPUN = 'R' may occasionally produce slightly worse
-C     or better estimates, and it is much faster than the option 'O'.
-C     When SEPD is computed and it is zero, the routine returns
-C     immediately, with RCOND and FERR (if requested) set to 0 and 1,
-C     respectively. In this case, the equation is singular.
-C
-C     Let B be an N-by-M matrix (if TRANA = 'N') or an M-by-N matrix
-C     (if TRANA = 'T' or 'C'), let R be an M-by-M symmetric positive
-C     definite matrix (R = R**T), and denote G = op(B)*inv(R)*op(B)'.
-C     Then, the Riccati equation (1) is equivalent to the standard
-C     discrete-time matrix algebraic Riccati equation
-C
-C         X = op(A)'*X*op(A) -                                       (4)
-C                                                -1
-C             op(A)'*X*op(B)*(R + op(B)'*X*op(B))  *op(B)'*X*op(A) + Q.
-C
-C     By symmetry, the equation (1) is also equivalent to
-C                               -1
-C         X = op(A)'*(I_n + X*G)  *X*op(A) + Q.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, and
-C     P.Hr. Petkov, Technical University of Sofia, March 1999.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2004.
-C
-C     KEYWORDS
-C
-C     Conditioning, error estimates, orthogonal transformation,
-C     real Schur form, Riccati equation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, FOUR, HALF
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
-     $                     FOUR = 4.0D+0, HALF = 0.5D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          FACT, JOB, LYAPUN, TRANA, UPLO
-      INTEGER            INFO, LDA, LDG, LDQ, LDT, LDU, LDWORK, LDX, N
-      DOUBLE PRECISION   FERR, RCOND, SEPD
-C     ..
-C     .. Array Arguments ..
-      INTEGER            IWORK( * )
-      DOUBLE PRECISION   A( LDA, * ), DWORK( * ),  G( LDG, * ),
-     $                   Q( LDQ, * ), T( LDT, * ), U( LDU, * ),
-     $                   X( LDX, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            JOBB, JOBC, JOBE, LOWER, NEEDAC, NOFACT,
-     $                   NOTRNA, UPDATE
-      CHARACTER          LOUP, SJOB, TRANAT
-      INTEGER            I, IABS, INFO2, IRES, IWRK, IXBS, IXMA, J, JJ,
-     $                   KASE, LDW, LWA, LWR, NN, SDIM, WRKOPT
-      DOUBLE PRECISION   ANORM, BIGNUM, DENOM, EPS, EPSN, EPST, EST,
-     $                   GNORM, PINORM, QNORM, SCALE, TEMP, THNORM,
-     $                   TMAX, XANORM, XNORM
-C     ..
-C     .. Local Arrays ..
-      LOGICAL            BWORK( 1 )
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME, SELECT
-      DOUBLE PRECISION   DLAMCH, DLANGE, DLANHS, DLANSY
-      EXTERNAL           DLAMCH, DLANGE, DLANHS, DLANSY, LSAME, SELECT
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DAXPY, DCOPY, DGEES, DGEMM, DGESV, DLACON,
-     $                   DLACPY, DLASET, DSCAL, DSWAP, DSYMM, MA02ED,
-     $                   MB01RU, MB01RX, MB01RY, MB01UD, SB03MX, SB03SX,
-     $                   SB03SY, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, DBLE, INT, MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode and Test input parameters.
-C
-      JOBC   = LSAME( JOB,    'C' )
-      JOBE   = LSAME( JOB,    'E' )
-      JOBB   = LSAME( JOB,    'B' )
-      NOFACT = LSAME( FACT,   'N' )
-      NOTRNA = LSAME( TRANA,  'N' )
-      LOWER  = LSAME( UPLO,   'L' )
-      UPDATE = LSAME( LYAPUN, 'O' )
-C
-      NEEDAC = UPDATE .AND. .NOT.JOBC
-C
-      NN = N*N
-      IF( UPDATE ) THEN
-         LWA = NN
-      ELSE
-         LWA = 0
-      END IF
-C
-      IF( JOBC ) THEN
-         LDW = MAX( 3, 2*NN ) + NN
-      ELSE
-         LDW = MAX( 3, 2*NN ) + 2*NN
-         IF( .NOT.UPDATE )
-     $      LDW = LDW + N
-      END IF
-      IF( NOFACT )
-     $   LDW = MAX( LWA + 5*N, LDW )
-C
-      INFO = 0
-      IF( .NOT.( JOBB .OR. JOBC .OR. JOBE ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( NOFACT .OR. LSAME( FACT,   'F' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.( NOTRNA .OR. LSAME( TRANA,  'T' ) .OR.
-     $                            LSAME( TRANA,  'C' ) ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT.( LOWER  .OR. LSAME( UPLO,   'U' ) ) ) THEN
-         INFO = -4
-      ELSE IF( .NOT.( UPDATE .OR. LSAME( LYAPUN, 'R' ) ) ) THEN
-         INFO = -5
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( LDA.LT.1 .OR.
-     $       ( LDA.LT.N .AND. ( UPDATE .OR. NOFACT ) ) ) THEN
-         INFO = -8
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -10
-      ELSE IF( LDU.LT.1 .OR. ( LDU.LT.N .AND. UPDATE ) ) THEN
-         INFO = -12
-      ELSE IF( LDG.LT.MAX( 1, N ) ) THEN
-         INFO = -14
-      ELSE IF( LDQ.LT.MAX( 1, N ) ) THEN
-         INFO = -16
-      ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
-         INFO = -18
-      ELSE IF( LDWORK.LT.LDW ) THEN
-         INFO = -24
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'SB02SD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( N.EQ.0 ) THEN
-         IF( .NOT.JOBE )
-     $      RCOND = ONE
-         IF( .NOT.JOBC )
-     $      FERR  = ZERO
-         DWORK( 1 ) = ONE
-         RETURN
-      END IF
-C
-C     Compute the 1-norm of the matrix X.
-C
-      XNORM = DLANSY( '1-norm', UPLO, N, X, LDX, DWORK )
-      IF( XNORM.EQ.ZERO ) THEN
-C
-C        The solution is zero.
-C
-         IF( .NOT.JOBE )
-     $      RCOND = ZERO
-         IF( .NOT.JOBC )
-     $      FERR  = ZERO
-         DWORK( 1 ) = DBLE( N )
-         RETURN
-      END IF
-C
-C     Workspace usage.
-C
-      IRES = 0
-      IXBS = IRES + NN
-      IXMA = MAX( 3, 2*NN )
-      IABS = IXMA + NN
-      IWRK = IABS + NN
-C
-C     Workspace:  LWK, where
-C                 LWK = 2*N*N, if LYAPUN = 'O', or FACT = 'N',
-C                 LWK = N,     otherwise.
-C
-      IF( UPDATE .OR. NOFACT ) THEN
-C
-         CALL DLASET( 'Full', N, N, ZERO, ONE, DWORK( IXBS+1 ), N )
-         CALL DSYMM(  'Left', UPLO, N, N, ONE, G, LDG, X, LDX, ONE,
-     $                DWORK( IXBS+1 ), N )
-         IF( NOTRNA ) THEN
-C                                   -1
-C           Compute Ac = (I_n + G*X)  *A.
-C
-            CALL DLACPY( 'Full', N, N, A, LDA, DWORK, N )
-            CALL DGESV( N, N, DWORK( IXBS+1 ), N, IWORK, DWORK, N,
-     $                  INFO2 )
-         ELSE
-C                                     -1
-C           Compute Ac = A*(I_n + X*G)  .
-C
-            DO 10 J = 1, N
-               CALL DCOPY( N, A( 1, J ), 1, DWORK( J ), N )
-   10       CONTINUE
-            CALL DGESV( N, N, DWORK( IXBS+1 ), N, IWORK, DWORK, N,
-     $                  INFO2 )
-            DO 20 J = 2, N
-               CALL DSWAP( J-1, DWORK( (J-1)*N+1 ), 1, DWORK( J ), N )
-   20       CONTINUE
-         END IF
-C
-         WRKOPT = DBLE( 2*NN )
-         IF( NOFACT )
-     $      CALL DLACPY( 'Full', N, N, DWORK, N, T, LDT )
-      ELSE
-         WRKOPT = DBLE( N )
-      END IF
-C
-      IF( NOFACT ) THEN
-C
-C        Compute the Schur factorization of Ac, Ac = U*T*U'.
-C        Workspace:  need   LWA + 5*N;
-C                    prefer larger;
-C                    LWA = N*N, if LYAPUN = 'O';
-C                    LWA = 0,   otherwise.
-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
-         IF( UPDATE ) THEN
-            SJOB = 'V'
-         ELSE
-            SJOB = 'N'
-         END IF
-         CALL DGEES( SJOB, 'Not ordered', SELECT, N, T, LDT, SDIM,
-     $               DWORK( LWA+1 ), DWORK( LWA+N+1 ), U, LDU,
-     $               DWORK( LWA+2*N+1 ), LDWORK-LWA-2*N, BWORK, INFO )
-         IF( INFO.GT.0 ) THEN
-            IF( LWA.GT.0 )
-     $         CALL DCOPY( 2*N, DWORK( LWA+1 ), 1, DWORK, 1 )
-            RETURN
-         END IF
-C
-         WRKOPT = MAX( WRKOPT, INT( DWORK( LWA+2*N+1 ) ) + LWA + 2*N )
-      END IF
-      IF( NEEDAC ) THEN
-         CALL DLACPY( 'Full', N, N, DWORK, N, DWORK( IABS+1 ), N )
-         LWR = NN
-      ELSE
-         LWR = 0
-      END IF
-C
-      IF( NOTRNA ) THEN
-         TRANAT = 'T'
-      ELSE
-         TRANAT = 'N'
-      END IF
-C                         _
-C     Compute X*op(Ac) or X*op(T).
-C
-      IF( UPDATE ) THEN
-         CALL DGEMM( 'NoTranspose', TRANA, N, N, N, ONE, X, LDX, DWORK,
-     $               N, ZERO, DWORK( IXMA+1 ), N )
-      ELSE
-         CALL MB01UD( 'Right', TRANA, N, N, ONE, T, LDT, X, LDX,
-     $                DWORK( IXMA+1 ), N, INFO2 )
-      END IF
-C
-      IF( .NOT.JOBE ) THEN
-C
-C        Estimate sepd(op(Ac),op(Ac)') = sepd(op(T),op(T)') and
-C        norm(Theta).
-C        Workspace LWR + MAX(3,2*N*N) + N*N, where
-C                  LWR = N*N, if LYAPUN = 'O' and JOB = 'B',
-C                  LWR = 0,   otherwise.
-C
-         CALL SB03SY( 'Both', TRANA, LYAPUN, N, T, LDT, U, LDU,
-     $                DWORK( IXMA+1 ), N, SEPD, THNORM, IWORK, DWORK,
-     $                IXMA, INFO )
-C
-         WRKOPT = MAX( WRKOPT, LWR + MAX( 3, 2*NN ) + NN )
-C
-C        Return if the equation is singular.
-C
-         IF( SEPD.EQ.ZERO ) THEN
-            RCOND = ZERO
-            IF( JOBB )
-     $         FERR = ONE
-            DWORK( 1 ) = DBLE( WRKOPT )
-            RETURN
-         END IF
-C
-C        Estimate norm(Pi).
-C        Workspace LWR + MAX(3,2*N*N) + N*N.
-C
-         KASE = 0
-C
-C        REPEAT
-   30    CONTINUE
-         CALL DLACON( NN, DWORK( IXBS+1 ), DWORK, IWORK, EST, KASE )
-         IF( KASE.NE.0 ) THEN
-C
-C           Select the triangular part of symmetric matrix to be used.
-C
-            IF( DLANSY( '1-norm', 'Upper', N, DWORK, N, DWORK( IXBS+1 ))
-     $          .GE.
-     $          DLANSY( '1-norm', 'Lower', N, DWORK, N, DWORK( IXBS+1 ))
-     $        ) THEN
-               LOUP = 'U'
-            ELSE
-               LOUP = 'L'
-            END IF
-C                                                        _   _
-C           Compute RHS = op(Ac)'*X*W*X*op(Ac) or op(T)'*X*W*X*op(T).
-C
-            CALL MB01RU( LOUP, TRANAT, N, N, ZERO, ONE, DWORK, N,
-     $                   DWORK( IXMA+1 ), N, DWORK, N, DWORK( IXBS+1 ),
-     $                   NN, INFO2 )
-            CALL DSCAL( N, HALF, DWORK, N+1 )
-C
-            IF( UPDATE ) THEN
-C
-C              Transform the right-hand side: RHS := U'*RHS*U.
-C
-               CALL MB01RU( LOUP, 'Transpose', N, N, ZERO, ONE, DWORK,
-     $                      N, U, LDU, DWORK, N, DWORK( IXBS+1 ), NN,
-     $                      INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-            END IF
-C
-C           Fill in the remaining triangle of the symmetric matrix.
-C
-            CALL MA02ED( LOUP, N, DWORK, N )
-C
-            IF( KASE.EQ.1 ) THEN
-C
-C              Solve op(T)'*Y*op(T) - Y = scale*RHS.
-C
-               CALL SB03MX( TRANA, N, T, LDT, DWORK, N, SCALE,
-     $                      DWORK( IXBS+1 ), INFO2 )
-            ELSE
-C
-C              Solve op(T)*W*op(T)' - W = scale*RHS.
-C
-               CALL SB03MX( TRANAT, N, T, LDT, DWORK, N, SCALE,
-     $                      DWORK( IXBS+1 ), INFO2 )
-            END IF
-C
-            IF( UPDATE ) THEN
-C
-C              Transform back to obtain the solution: Z := U*Z*U', with
-C              Z = Y or Z = W.
-C
-               CALL MB01RU( LOUP, 'No transpose', N, N, ZERO, ONE,
-     $                      DWORK, N, U, LDU, DWORK, N, DWORK( IXBS+1 ),
-     $                      NN, INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-C
-C              Fill in the remaining triangle of the symmetric matrix.
-C
-               CALL MA02ED( LOUP, N, DWORK, N )
-            END IF
-            GO TO 30
-         END IF
-C        UNTIL KASE = 0
-C
-         IF( EST.LT.SCALE ) THEN
-            PINORM = EST / SCALE
-         ELSE
-            BIGNUM = ONE / DLAMCH( 'Safe minimum' )
-            IF( EST.LT.SCALE*BIGNUM ) THEN
-               PINORM = EST / SCALE
-            ELSE
-               PINORM = BIGNUM
-            END IF
-         END IF
-C
-C        Compute the 1-norm of A or T.
-C
-         IF( UPDATE ) THEN
-            ANORM = DLANGE( '1-norm', N, N, A, LDA, DWORK )
-         ELSE
-            ANORM = DLANHS( '1-norm', N, T, LDT, DWORK )
-         END IF
-C
-C        Compute the 1-norms of the matrices Q and G.
-C
-         QNORM = DLANSY( '1-norm', UPLO, N, Q, LDQ, DWORK )
-         GNORM = DLANSY( '1-norm', UPLO, N, G, LDG, DWORK )
-C
-C        Estimate the reciprocal condition number.
-C
-         TMAX = MAX( SEPD, XNORM, ANORM, GNORM )
-         IF( TMAX.LE.ONE ) THEN
-            TEMP  = SEPD*XNORM
-            DENOM = QNORM + ( SEPD*ANORM )*THNORM +
-     $                      ( SEPD*GNORM )*PINORM
-         ELSE
-            TEMP  =   ( SEPD / TMAX )*( XNORM / TMAX )
-            DENOM = ( ( ONE  / TMAX )*( QNORM / TMAX ) ) +
-     $              ( ( SEPD / TMAX )*( ANORM / TMAX ) )*THNORM +
-     $              ( ( SEPD / TMAX )*( GNORM / TMAX ) )*PINORM
-         END IF
-         IF( TEMP.GE.DENOM ) THEN
-            RCOND = ONE
-         ELSE
-            RCOND = TEMP / DENOM
-         END IF
-      END IF
-C
-      IF( .NOT.JOBC ) THEN
-C
-C        Form a triangle of the residual matrix
-C          R = op(Ac)'*X*op(Ac) + op(Ac)'*X*G*X*op(Ac) + Q - X,
-C        or           _                _ _ _         _   _
-C          R = op(T)'*X*op(T) + op(T)'*X*G*X*op(T) + Q - X,
-C        exploiting the symmetry. Actually, the equivalent formula
-C          R = op(A)'*X*op(Ac) + Q - X
-C        is used in the first case.
-C        Workspace MAX(3,2*N*N) + 2*N*N,     if LYAPUN = 'O';
-C                  MAX(3,2*N*N) + 2*N*N + N, if LYAPUN = 'R'.
-C
-         CALL DLACPY( UPLO, N, N, Q, LDQ, DWORK( IRES+1 ), N )
-         JJ = IRES + 1
-         IF( LOWER ) THEN
-            DO 40 J = 1, N
-               CALL DAXPY( N-J+1, -ONE, X( J, J ), 1, DWORK( JJ ), 1 )
-               JJ = JJ + N + 1
-   40       CONTINUE
-         ELSE
-            DO 50 J = 1, N
-               CALL DAXPY( J, -ONE, X( 1, J ), 1, DWORK( JJ ), 1 )
-               JJ = JJ + N
-   50       CONTINUE
-         END IF
-C
-         IF( UPDATE ) THEN
-            CALL MB01RX( 'Left', UPLO, TRANAT, N, N, ONE, ONE,
-     $                   DWORK( IRES+1 ), N, A, LDA, DWORK( IXMA+1 ), N,
-     $                   INFO2 )
-         ELSE
-            CALL MB01RY( 'Left', UPLO, TRANAT, N, ONE, ONE,
-     $                   DWORK( IRES+1 ), N, T, LDT, DWORK( IXMA+1 ), N,
-     $                   DWORK( IWRK+1 ), INFO2 )
-            CALL DSYMM(  'Left', UPLO, N, N, ONE, G, LDG,
-     $                   DWORK( IXMA+1 ), N, ZERO, DWORK( IXBS+1 ), N )
-            CALL MB01RX( 'Left', UPLO, 'Transpose', N, N, ONE, ONE,
-     $                   DWORK( IRES+1 ), N, DWORK( IXMA+1 ), N,
-     $                   DWORK( IXBS+1 ), N, INFO2 )
-         END IF
-C
-C        Get the machine precision.
-C
-         EPS  = DLAMCH( 'Epsilon' )
-         EPSN = EPS*DBLE( N + 4 )
-         EPST = EPS*DBLE( 2*( N + 1 ) )
-         TEMP = EPS*FOUR
-C
-C        Add to abs(R) a term that takes account of rounding errors in
-C        forming R:
-C         abs(R) := abs(R) + EPS*(4*abs(Q) + 4*abs(X) +
-C                   (n+4)*abs(op(Ac))'*abs(X)*abs(op(Ac)) + 2*(n+1)*
-C                   abs(op(Ac))'*abs(X)*abs(G)*abs(X)*abs(op(Ac))),
-C        or                             _          _
-C         abs(R) := abs(R) + EPS*(4*abs(Q) + 4*abs(X) +
-C                                         _
-C                   (n+4)*abs(op(T))'*abs(X)*abs(op(T)) +
-C                                         _      _      _
-C                 2*(n+1)*abs(op(T))'*abs(X)*abs(G)*abs(X)*abs(op(T))),
-C        where EPS is the machine precision.
-C
-         DO 70 J = 1, N
-            DO 60 I = 1, N
-               DWORK( IXBS+(J-1)*N+I ) = ABS( X( I, J ) )
-   60       CONTINUE
-   70    CONTINUE
-C
-         IF( LOWER ) THEN
-            DO 90 J = 1, N
-               DO 80 I = J, N
-                  DWORK( IRES+(J-1)*N+I ) = TEMP*( ABS( Q( I, J ) ) +
-     $                                             ABS( X( I, J ) ) ) +
-     $                                 ABS( DWORK( IRES+(J-1)*N+I ) )
-   80          CONTINUE
-   90       CONTINUE
-         ELSE
-            DO 110 J = 1, N
-               DO 100 I = 1, J
-                  DWORK( IRES+(J-1)*N+I ) = TEMP*( ABS( Q( I, J ) ) +
-     $                                             ABS( X( I, J ) ) ) +
-     $                                 ABS( DWORK( IRES+(J-1)*N+I ) )
-  100          CONTINUE
-  110       CONTINUE
-         END IF
-C
-         IF( UPDATE ) THEN
-C
-            DO 130 J = 1, N
-               DO 120 I = 1, N
-                  DWORK( IABS+(J-1)*N+I ) =
-     $               ABS( DWORK( IABS+(J-1)*N+I ) )
-  120          CONTINUE
-  130       CONTINUE
-C
-            CALL DGEMM( 'NoTranspose', TRANA, N, N, N, ONE,
-     $                  DWORK( IXBS+1 ), N, DWORK( IABS+1 ), N, ZERO,
-     $                  DWORK( IXMA+1 ), N )
-            CALL MB01RX( 'Left', UPLO, TRANAT, N, N, ONE, EPSN,
-     $                   DWORK( IRES+1 ), N, DWORK( IABS+1 ), N,
-     $                   DWORK( IXMA+1 ), N, INFO2 )
-         ELSE
-C
-            DO 150 J = 1, N
-               DO 140 I = 1, MIN( J+1, N )
-                  DWORK( IABS+(J-1)*N+I ) = ABS( T( I, J ) )
-  140          CONTINUE
-  150       CONTINUE
-C
-            CALL MB01UD( 'Right', TRANA, N, N, ONE, DWORK( IABS+1 ), N,
-     $                   DWORK( IXBS+1 ), N, DWORK( IXMA+1 ), N, INFO2 )
-            CALL MB01RY( 'Left', UPLO, TRANAT, N, ONE, EPSN,
-     $                   DWORK( IRES+1 ), N, DWORK( IABS+1 ), N,
-     $                   DWORK( IXMA+1 ), N, DWORK( IWRK+1 ), INFO2 )
-         END IF
-C
-         IF( LOWER ) THEN
-            DO 170 J = 1, N
-               DO 160 I = J, N
-                  DWORK( IABS+(J-1)*N+I ) = ABS( G( I, J ) )
-  160          CONTINUE
-  170       CONTINUE
-         ELSE
-            DO 190 J = 1, N
-               DO 180 I = 1, J
-                  DWORK( IABS+(J-1)*N+I ) = ABS( G( I, J ) )
-  180          CONTINUE
-  190       CONTINUE
-         END IF
-C
-         IF( UPDATE ) THEN
-            CALL MB01RU( UPLO, TRANAT, N, N, ONE, EPST, DWORK( IRES+1 ),
-     $                   N, DWORK( IXMA+1 ), N, DWORK( IABS+1 ), N,
-     $                   DWORK( IXBS+1 ), NN, INFO2 )
-            WRKOPT = MAX( WRKOPT, MAX( 3, 2*NN ) + 2*NN )
-         ELSE
-            CALL DSYMM(  'Left', UPLO, N, N, ONE,  DWORK( IABS+1 ), N,
-     $                   DWORK( IXMA+1 ), N, ZERO, DWORK( IXBS+1 ), N )
-            CALL MB01RY( 'Left', UPLO, TRANAT, N, ONE, EPST,
-     $                   DWORK( IRES+1 ), N, DWORK( IXMA+1 ), N,
-     $                   DWORK( IXBS+1 ), N, DWORK( IWRK+1 ), INFO2 )
-            WRKOPT = MAX( WRKOPT, MAX( 3, 2*NN ) + 2*NN + N )
-         END IF
-C
-C        Compute forward error bound, using matrix norm estimator.
-C        Workspace MAX(3,2*N*N) + N*N.
-C
-         XANORM = DLANSY( 'Max', UPLO, N, X, LDX, DWORK )
-C
-         CALL SB03SX( TRANA, UPLO, LYAPUN, N, XANORM, T, LDT, U, LDU,
-     $                DWORK( IRES+1 ), N, FERR, IWORK, DWORK( IXBS+1 ),
-     $                IXMA, INFO )
-      END IF
-C
-      DWORK( 1 ) = DBLE( WRKOPT )
-      RETURN
-C
-C *** Last line of SB02SD ***
-      END
--- a/extra/control-devel/src/SB03MV.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,295 +0,0 @@
-      SUBROUTINE SB03MV( LTRAN, LUPPER, T, LDT, B, LDB, SCALE, X, LDX,
-     $                   XNORM, 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 the 2-by-2 symmetric matrix X in
-C
-C            op(T)'*X*op(T) - X = SCALE*B,
-C
-C     where T is 2-by-2, B is symmetric 2-by-2, and op(T) = T or T',
-C     where T' denotes the transpose of T.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     LTRAN   LOGICAL
-C             Specifies the form of op(T) to be used, as follows:
-C             = .FALSE.:  op(T) = T,
-C             = .TRUE. :  op(T) = T'.
-C
-C     LUPPER  LOGICAL
-C             Specifies which triangle of the matrix B is used, and
-C             which triangle of the matrix X is computed, as follows:
-C             = .TRUE. :  The upper triangular part;
-C             = .FALSE.:  The lower triangular part.
-C
-C     Input/Output Parameters
-C
-C     T       (input) DOUBLE PRECISION array, dimension (LDT,2)
-C             The leading 2-by-2 part of this array must contain the
-C             matrix T.
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.  LDT >= 2.
-C
-C     B       (input) DOUBLE PRECISION array, dimension (LDB,2)
-C             On entry with LUPPER = .TRUE., the leading 2-by-2 upper
-C             triangular part of this array must contain the upper
-C             triangular part of the symmetric matrix B and the strictly
-C             lower triangular part of B is not referenced.
-C             On entry with LUPPER = .FALSE., the leading 2-by-2 lower
-C             triangular part of this array must contain the lower
-C             triangular part of the symmetric matrix B and the strictly
-C             upper triangular part of B is not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= 2.
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor. SCALE is chosen less than or equal to 1
-C             to prevent the solution overflowing.
-C
-C     X       (output) DOUBLE PRECISION array, dimension (LDX,2)
-C             On exit with LUPPER = .TRUE., the leading 2-by-2 upper
-C             triangular part of this array contains the upper
-C             triangular part of the symmetric solution matrix X and the
-C             strictly lower triangular part of X is not referenced.
-C             On exit with LUPPER = .FALSE., the leading 2-by-2 lower
-C             triangular part of this array contains the lower
-C             triangular part of the symmetric solution matrix X and the
-C             strictly upper triangular part of X is not referenced.
-C             Note that X may be identified with B in the calling
-C             statement.
-C
-C     LDX     INTEGER
-C             The leading dimension of array X.  LDX >= 2.
-C
-C     XNORM   (output) DOUBLE PRECISION
-C             The infinity-norm of the solution.
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             = 0:  successful exit;
-C             = 1:  if T has almost reciprocal eigenvalues, so T
-C                   is perturbed to get a nonsingular equation.
-C
-C             NOTE: In the interests of speed, this routine does not
-C                   check the inputs for errors.
-C
-C     METHOD
-C
-C     The equivalent linear algebraic system of equations is formed and
-C     solved using Gaussian elimination with complete pivoting.
-C
-C     REFERENCES
-C
-C     [1] Anderson, E., Bai, Z., Bischof, C., Demmel, J., Dongarra, J.,
-C         Du Croz, J., Greenbaum, A., Hammarling, S., McKenney, A.,
-C         Ostrouchov, S., and Sorensen, D.
-C         LAPACK Users' Guide: Second Edition.
-C         SIAM, Philadelphia, 1995.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is stable and reliable, since Gaussian elimination
-C     with complete pivoting is used.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, May 1997.
-C     Based on DLALD2 by P. Petkov, Tech. University of Sofia, September
-C     1993.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Discrete-time system, Lyapunov equation, matrix algebra.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, FOUR
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
-     $                     FOUR = 4.0D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      LOGICAL            LTRAN, LUPPER
-      INTEGER            INFO, LDB, LDT, LDX
-      DOUBLE PRECISION   SCALE, XNORM
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   B( LDB, * ), T( LDT, * ), X( LDX, * )
-C     ..
-C     .. Local Scalars ..
-      INTEGER            I, IP, IPSV, J, JP, JPSV, K
-      DOUBLE PRECISION   EPS, SMIN, SMLNUM, TEMP, XMAX
-C     ..
-C     .. Local Arrays ..
-      INTEGER            JPIV( 3 )
-      DOUBLE PRECISION   BTMP( 3 ), T9( 3, 3 ), TMP( 3 )
-C     ..
-C     .. External Functions ..
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           DLAMCH
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DSWAP
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, MAX
-C     ..
-C     .. Executable Statements ..
-C
-C     Do not check the input parameters for errors.
-C
-      INFO = 0
-C
-C     Set constants to control overflow.
-C
-      EPS = DLAMCH( 'P' )
-      SMLNUM = DLAMCH( 'S' ) / EPS
-C
-C     Solve equivalent 3-by-3 system using complete pivoting.
-C     Set pivots less than SMIN to SMIN.
-C
-      SMIN = MAX( ABS( T( 1, 1 ) ), ABS( T( 1, 2 ) ),
-     $            ABS( T( 2, 1 ) ), ABS( T( 2, 2 ) ) )
-      SMIN = MAX( EPS*SMIN, SMLNUM )
-      T9( 1, 1 ) = T( 1, 1 )*T( 1, 1 ) - ONE
-      T9( 2, 2 ) = T( 1, 1 )*T( 2, 2 ) + T( 1, 2 )*T( 2, 1 ) - ONE
-      T9( 3, 3 ) = T( 2, 2 )*T( 2, 2 ) - ONE
-      IF( LTRAN ) THEN
-         T9( 1, 2 ) = T( 1, 1 )*T( 1, 2 ) + T( 1, 1 )*T( 1, 2 )
-         T9( 1, 3 ) = T( 1, 2 )*T( 1, 2 )
-         T9( 2, 1 ) = T( 1, 1 )*T( 2, 1 )
-         T9( 2, 3 ) = T( 1, 2 )*T( 2, 2 )
-         T9( 3, 1 ) = T( 2, 1 )*T( 2, 1 )
-         T9( 3, 2 ) = T( 2, 1 )*T( 2, 2 ) + T( 2, 1 )*T( 2, 2 )
-      ELSE
-         T9( 1, 2 ) = T( 1, 1 )*T( 2, 1 ) + T( 1, 1 )*T( 2, 1 )
-         T9( 1, 3 ) = T( 2, 1 )*T( 2, 1 )
-         T9( 2, 1 ) = T( 1, 1 )*T( 1, 2 )
-         T9( 2, 3 ) = T( 2, 1 )*T( 2, 2 )
-         T9( 3, 1 ) = T( 1, 2 )*T( 1, 2 )
-         T9( 3, 2 ) = T( 1, 2 )*T( 2, 2 ) + T( 1, 2 )*T( 2, 2 )
-      END IF
-      BTMP( 1 ) = B( 1, 1 )
-      IF ( LUPPER ) THEN
-         BTMP( 2 ) = B( 1, 2 )
-      ELSE
-         BTMP( 2 ) = B( 2, 1 )
-      END IF
-      BTMP( 3 ) = B( 2, 2 )
-C
-C     Perform elimination.
-C
-      DO 50 I = 1, 2
-         XMAX = ZERO
-C
-         DO 20 IP = I, 3
-C
-            DO 10 JP = I, 3
-               IF( ABS( T9( IP, JP ) ).GE.XMAX ) THEN
-                  XMAX = ABS( T9( IP, JP ) )
-                  IPSV = IP
-                  JPSV = JP
-               END IF
-   10       CONTINUE
-C
-   20    CONTINUE
-C
-         IF( IPSV.NE.I ) THEN
-            CALL DSWAP( 3, T9( IPSV, 1 ), 3, T9( I, 1 ), 3 )
-            TEMP = BTMP( I )
-            BTMP( I ) = BTMP( IPSV )
-            BTMP( IPSV ) = TEMP
-         END IF
-         IF( JPSV.NE.I )
-     $      CALL DSWAP( 3, T9( 1, JPSV ), 1, T9( 1, I ), 1 )
-         JPIV( I ) = JPSV
-         IF( ABS( T9( I, I ) ).LT.SMIN ) THEN
-            INFO = 1
-            T9( I, I ) = SMIN
-         END IF
-C
-         DO 40 J = I + 1, 3
-            T9( J, I ) = T9( J, I ) / T9( I, I )
-            BTMP( J ) = BTMP( J ) - T9( J, I )*BTMP( I )
-C
-            DO 30 K = I + 1, 3
-               T9( J, K ) = T9( J, K ) - T9( J, I )*T9( I, K )
-   30       CONTINUE
-C
-   40    CONTINUE
-C
-   50 CONTINUE
-C
-      IF( ABS( T9( 3, 3 ) ).LT.SMIN )
-     $   T9( 3, 3 ) = SMIN
-      SCALE = ONE
-      IF( ( FOUR*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( T9( 1, 1 ) ) .OR.
-     $    ( FOUR*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( T9( 2, 2 ) ) .OR.
-     $    ( FOUR*SMLNUM )*ABS( BTMP( 3 ) ).GT.ABS( T9( 3, 3 ) ) ) THEN
-         SCALE = ( ONE / FOUR ) / MAX( ABS( BTMP( 1 ) ),
-     $               ABS( BTMP( 2 ) ), ABS( BTMP( 3 ) ) )
-         BTMP( 1 ) = BTMP( 1 )*SCALE
-         BTMP( 2 ) = BTMP( 2 )*SCALE
-         BTMP( 3 ) = BTMP( 3 )*SCALE
-      END IF
-C
-      DO 70 I = 1, 3
-         K = 4 - I
-         TEMP = ONE / T9( K, K )
-         TMP( K ) = BTMP( K )*TEMP
-C
-         DO 60 J = K + 1, 3
-            TMP( K ) = TMP( K ) - ( TEMP*T9( K, J ) )*TMP( J )
-  60     CONTINUE
-C
-  70  CONTINUE
-C
-      DO 80 I = 1, 2
-         IF( JPIV( 3-I ).NE.3-I ) THEN
-            TEMP = TMP( 3-I )
-            TMP( 3-I ) = TMP( JPIV( 3-I ) )
-            TMP( JPIV( 3-I ) ) = TEMP
-         END IF
-  80  CONTINUE
-C
-      X( 1, 1 ) = TMP( 1 )
-      IF ( LUPPER ) THEN
-         X( 1, 2 ) = TMP( 2 )
-      ELSE
-         X( 2, 1 ) = TMP( 2 )
-      END IF
-      X( 2, 2 ) = TMP( 3 )
-      XNORM = MAX( ABS( TMP( 1 ) ) + ABS( TMP( 2 ) ),
-     $             ABS( TMP( 2 ) ) + ABS( TMP( 3 ) ) )
-C
-      RETURN
-C *** Last line of SB03MV ***
-      END
--- a/extra/control-devel/src/SB03MW.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,293 +0,0 @@
-      SUBROUTINE SB03MW( LTRAN, LUPPER, T, LDT, B, LDB, SCALE, X, LDX,
-     $                   XNORM, 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 the 2-by-2 symmetric matrix X in
-C
-C            op(T)'*X + X*op(T) = SCALE*B,
-C
-C     where T is 2-by-2, B is symmetric 2-by-2, and op(T) = T or T',
-C     where T' denotes the transpose of T.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     LTRAN   LOGICAL
-C             Specifies the form of op(T) to be used, as follows:
-C             = .FALSE.:  op(T) = T,
-C             = .TRUE. :  op(T) = T'.
-C
-C     LUPPER  LOGICAL
-C             Specifies which triangle of the matrix B is used, and
-C             which triangle of the matrix X is computed, as follows:
-C             = .TRUE. :  The upper triangular part;
-C             = .FALSE.:  The lower triangular part.
-C
-C     Input/Output Parameters
-C
-C     T       (input) DOUBLE PRECISION array, dimension (LDT,2)
-C             The leading 2-by-2 part of this array must contain the
-C             matrix T.
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.  LDT >= 2.
-C
-C     B       (input) DOUBLE PRECISION array, dimension (LDB,2)
-C             On entry with LUPPER = .TRUE., the leading 2-by-2 upper
-C             triangular part of this array must contain the upper
-C             triangular part of the symmetric matrix B and the strictly
-C             lower triangular part of B is not referenced.
-C             On entry with LUPPER = .FALSE., the leading 2-by-2 lower
-C             triangular part of this array must contain the lower
-C             triangular part of the symmetric matrix B and the strictly
-C             upper triangular part of B is not referenced.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= 2.
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor. SCALE is chosen less than or equal to 1
-C             to prevent the solution overflowing.
-C
-C     X       (output) DOUBLE PRECISION array, dimension (LDX,2)
-C             On exit with LUPPER = .TRUE., the leading 2-by-2 upper
-C             triangular part of this array contains the upper
-C             triangular part of the symmetric solution matrix X and the
-C             strictly lower triangular part of X is not referenced.
-C             On exit with LUPPER = .FALSE., the leading 2-by-2 lower
-C             triangular part of this array contains the lower
-C             triangular part of the symmetric solution matrix X and the
-C             strictly upper triangular part of X is not referenced.
-C             Note that X may be identified with B in the calling
-C             statement.
-C
-C     LDX     INTEGER
-C             The leading dimension of array X.  LDX >= 2.
-C
-C     XNORM   (output) DOUBLE PRECISION
-C             The infinity-norm of the solution.
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             = 0:  successful exit;
-C             = 1:  if T and -T have too close eigenvalues, so T
-C                   is perturbed to get a nonsingular equation.
-C
-C             NOTE: In the interests of speed, this routine does not
-C                   check the inputs for errors.
-C
-C     METHOD
-C
-C     The equivalent linear algebraic system of equations is formed and
-C     solved using Gaussian elimination with complete pivoting.
-C
-C     REFERENCES
-C
-C     [1] Anderson, E., Bai, Z., Bischof, C., Demmel, J., Dongarra, J.,
-C         Du Croz, J., Greenbaum, A., Hammarling, S., McKenney, A.,
-C         Ostrouchov, S., and Sorensen, D.
-C         LAPACK Users' Guide: Second Edition.
-C         SIAM, Philadelphia, 1995.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is stable and reliable, since Gaussian elimination
-C     with complete pivoting is used.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, May 1997.
-C     Based on DLALY2 by P. Petkov, Tech. University of Sofia, September
-C     1993.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Continuous-time system, Lyapunov equation, matrix algebra.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, FOUR
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
-     $                     FOUR = 4.0D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      LOGICAL            LTRAN, LUPPER
-      INTEGER            INFO, LDB, LDT, LDX
-      DOUBLE PRECISION   SCALE, XNORM
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   B( LDB, * ), T( LDT, * ), X( LDX, * )
-C     ..
-C     .. Local Scalars ..
-      INTEGER            I, IP, IPSV, J, JP, JPSV, K
-      DOUBLE PRECISION   EPS, SMIN, SMLNUM, TEMP, XMAX
-C     ..
-C     .. Local Arrays ..
-      INTEGER            JPIV( 3 )
-      DOUBLE PRECISION   BTMP( 3 ), T9( 3, 3 ), TMP( 3 )
-C     ..
-C     .. External Functions ..
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           DLAMCH
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DSWAP
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, MAX
-C     ..
-C     .. Executable Statements ..
-C
-C     Do not check the input parameters for errors
-C
-      INFO = 0
-C
-C     Set constants to control overflow
-C
-      EPS = DLAMCH( 'P' )
-      SMLNUM = DLAMCH( 'S' ) / EPS
-C
-C     Solve equivalent 3-by-3 system using complete pivoting.
-C     Set pivots less than SMIN to SMIN.
-C
-      SMIN = MAX( MAX( ABS( T( 1, 1 ) ), ABS( T( 1, 2 ) ),
-     $                 ABS( T( 2, 1 ) ), ABS( T( 2, 2 ) ) )*EPS,
-     $            SMLNUM )
-      T9( 1, 3 ) = ZERO
-      T9( 3, 1 ) = ZERO
-      T9( 1, 1 ) = T( 1, 1 )
-      T9( 2, 2 ) = T( 1, 1 ) + T( 2, 2 )
-      T9( 3, 3 ) = T( 2, 2 )
-      IF( LTRAN ) THEN
-         T9( 1, 2 ) = T( 1, 2 )
-         T9( 2, 1 ) = T( 2, 1 )
-         T9( 2, 3 ) = T( 1, 2 )
-         T9( 3, 2 ) = T( 2, 1 )
-      ELSE
-         T9( 1, 2 ) = T( 2, 1 )
-         T9( 2, 1 ) = T( 1, 2 )
-         T9( 2, 3 ) = T( 2, 1 )
-         T9( 3, 2 ) = T( 1, 2 )
-      END IF
-      BTMP( 1 ) = B( 1, 1 )/TWO
-      IF ( LUPPER ) THEN
-         BTMP( 2 ) = B( 1, 2 )
-      ELSE
-         BTMP( 2 ) = B( 2, 1 )
-      END IF
-      BTMP( 3 ) = B( 2, 2 )/TWO
-C
-C     Perform elimination
-C
-      DO 50 I = 1, 2
-         XMAX = ZERO
-C
-         DO 20 IP = I, 3
-C
-            DO 10 JP = I, 3
-               IF( ABS( T9( IP, JP ) ).GE.XMAX ) THEN
-                  XMAX = ABS( T9( IP, JP ) )
-                  IPSV = IP
-                  JPSV = JP
-               END IF
-   10       CONTINUE
-C
-   20    CONTINUE
-C
-         IF( IPSV.NE.I ) THEN
-            CALL DSWAP( 3, T9( IPSV, 1 ), 3, T9( I, 1 ), 3 )
-            TEMP = BTMP( I )
-            BTMP( I ) = BTMP( IPSV )
-            BTMP( IPSV ) = TEMP
-         END IF
-         IF( JPSV.NE.I )
-     $      CALL DSWAP( 3, T9( 1, JPSV ), 1, T9( 1, I ), 1 )
-         JPIV( I ) = JPSV
-         IF( ABS( T9( I, I ) ).LT.SMIN ) THEN
-            INFO = 1
-            T9( I, I ) = SMIN
-         END IF
-C
-         DO 40 J = I + 1, 3
-            T9( J, I ) = T9( J, I ) / T9( I, I )
-            BTMP( J ) = BTMP( J ) - T9( J, I )*BTMP( I )
-C
-            DO 30 K = I + 1, 3
-               T9( J, K ) = T9( J, K ) - T9( J, I )*T9( I, K )
-   30       CONTINUE
-C
-   40    CONTINUE
-C
-   50 CONTINUE
-C
-      IF( ABS( T9( 3, 3 ) ).LT.SMIN )
-     $   T9( 3, 3 ) = SMIN
-      SCALE = ONE
-      IF( ( FOUR*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( T9( 1, 1 ) ) .OR.
-     $    ( FOUR*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( T9( 2, 2 ) ) .OR.
-     $    ( FOUR*SMLNUM )*ABS( BTMP( 3 ) ).GT.ABS( T9( 3, 3 ) ) ) THEN
-         SCALE = ( ONE / FOUR ) / MAX( ABS( BTMP( 1 ) ),
-     $               ABS( BTMP( 2 ) ), ABS( BTMP( 3 ) ) )
-         BTMP( 1 ) = BTMP( 1 )*SCALE
-         BTMP( 2 ) = BTMP( 2 )*SCALE
-         BTMP( 3 ) = BTMP( 3 )*SCALE
-      END IF
-C
-      DO 70 I = 1, 3
-         K = 4 - I
-         TEMP = ONE / T9( K, K )
-         TMP( K ) = BTMP( K )*TEMP
-C
-         DO 60 J = K + 1, 3
-            TMP( K ) = TMP( K ) - ( TEMP*T9( K, J ) )*TMP( J )
-  60     CONTINUE
-C
-  70  CONTINUE
-C
-      DO 80 I = 1, 2
-         IF( JPIV( 3-I ).NE.3-I ) THEN
-            TEMP = TMP( 3-I )
-            TMP( 3-I ) = TMP( JPIV( 3-I ) )
-            TMP( JPIV( 3-I ) ) = TEMP
-         END IF
-  80  CONTINUE
-C
-      X( 1, 1 ) = TMP( 1 )
-      IF ( LUPPER ) THEN
-         X( 1, 2 ) = TMP( 2 )
-      ELSE
-         X( 2, 1 ) = TMP( 2 )
-      END IF
-      X( 2, 2 ) = TMP( 3 )
-      XNORM = MAX( ABS( TMP( 1 ) ) + ABS( TMP( 2 ) ),
-     $             ABS( TMP( 2 ) ) + ABS( TMP( 3 ) ) )
-C
-      RETURN
-C *** Last line of SB03MW ***
-      END
--- a/extra/control-devel/src/SB03MX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,711 +0,0 @@
-      SUBROUTINE SB03MX( TRANA, N, A, LDA, C, LDC, SCALE, DWORK, 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 the real discrete Lyapunov matrix equation
-C
-C            op(A)'*X*op(A) - X = scale*C
-C
-C     where op(A) = A or A' (A**T), A is upper quasi-triangular and C is
-C     symmetric (C = C'). (A' denotes the transpose of the matrix A.)
-C     A is N-by-N, the right hand side C and the solution X are N-by-N,
-C     and scale is an output scale factor, set less than or equal to 1
-C     to avoid overflow in X. The solution matrix X is overwritten
-C     onto C.
-C
-C     A must be in Schur canonical form (as returned by LAPACK routines
-C     DGEES or DHSEQR), that is, block upper triangular with 1-by-1 and
-C     2-by-2 diagonal blocks; each 2-by-2 diagonal block has its
-C     diagonal elements equal and its off-diagonal elements of opposite
-C     sign.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A, X, and C.  N >= 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             upper quasi-triangular matrix A, in Schur canonical form.
-C             The part of A below the first sub-diagonal is not
-C             referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the symmetric matrix C.
-C             On exit, if INFO >= 0, the leading N-by-N part of this
-C             array contains the symmetric solution matrix X.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,N).
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor, scale, set less than or equal to 1 to
-C             prevent the solution overflowing.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION 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 A has almost reciprocal eigenvalues; perturbed
-C                   values were used to solve the equation (but the
-C                   matrix A is unchanged).
-C
-C     METHOD
-C
-C     A discrete-time version of the Bartels-Stewart algorithm is used.
-C     A set of equivalent linear algebraic systems of equations of order
-C     at most four are formed and solved using Gaussian elimination with
-C     complete pivoting.
-C
-C     REFERENCES
-C
-C     [1] Barraud, A.Y.                   T
-C         A numerical algorithm to solve A XA - X = Q.
-C         IEEE Trans. Auto. Contr., AC-22, pp. 883-885, 1977.
-C
-C     [2] Bartels, R.H. and Stewart, G.W.  T
-C         Solution of the matrix equation A X + XB = C.
-C         Comm. A.C.M., 15, pp. 820-826, 1972.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, May 1997.
-C     Supersedes Release 2.0 routine SB03AZ by Control Systems Research
-C     Group, Kingston Polytechnic, United Kingdom, October 1982.
-C     Based on DTRLPD by P. Petkov, Tech. University of Sofia, September
-C     1993.
-C
-C     REVISIONS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, May 1999.
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 2000.
-C     A. Varga, DLR Oberpfaffenhofen, March 2002.
-C
-C     KEYWORDS
-C
-C     Discrete-time system, Lyapunov equation, matrix algebra, real
-C     Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          TRANA
-      INTEGER            INFO, LDA, LDC, N
-      DOUBLE PRECISION   SCALE
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), DWORK( * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            NOTRNA, LUPPER
-      INTEGER            IERR, J, K, K1, K2, KNEXT, L, L1, L2, LNEXT,
-     $                   MINK1N, MINK2N, MINL1N, MINL2N, NP1
-      DOUBLE PRECISION   A11, BIGNUM, DA11, DB, EPS, P11, P12, P21, P22,
-     $                   SCALOC, SMIN, SMLNUM, XNORM
-C     ..
-C     .. Local Arrays ..
-      DOUBLE PRECISION   VEC( 2, 2 ), X( 2, 2 )
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DDOT, DLAMCH, DLANHS
-      EXTERNAL           DDOT, DLAMCH, DLANHS, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DLABAD, DLALN2, DSCAL, DSYMV, SB03MV, SB04PX,
-     $                   XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, DBLE, MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode and Test input parameters.
-C
-      NOTRNA = LSAME( TRANA, 'N' )
-      LUPPER = .TRUE.
-C
-      INFO = 0
-      IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'T' ) .AND.
-     $                      .NOT.LSAME( TRANA, 'C' ) ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -4
-      ELSE IF( LDC.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'SB03MX', -INFO )
-         RETURN
-      END IF
-C
-      SCALE = ONE
-C
-C     Quick return if possible.
-C
-      IF( N.EQ.0 )
-     $   RETURN
-C
-C     Set constants to control overflow.
-C
-      EPS = DLAMCH( 'P' )
-      SMLNUM = DLAMCH( 'S' )
-      BIGNUM = ONE / SMLNUM
-      CALL DLABAD( SMLNUM, BIGNUM )
-      SMLNUM = SMLNUM*DBLE( N*N ) / EPS
-      BIGNUM = ONE / SMLNUM
-C
-      SMIN = MAX( SMLNUM, EPS*DLANHS( 'Max', N, A, LDA, DWORK ) )
-      NP1  = N + 1
-C
-      IF( NOTRNA ) THEN
-C
-C        Solve    A'*X*A - X = scale*C.
-C
-C        The (K,L)th block of X is determined starting from
-C        upper-left corner column by column by
-C
-C          A(K,K)'*X(K,L)*A(L,L) - X(K,L) = C(K,L) - R(K,L),
-C
-C        where
-C                    K           L-1
-C          R(K,L) = SUM {A(I,K)'*SUM [X(I,J)*A(J,L)]} +
-C                   I=1          J=1
-C
-C                    K-1
-C                   {SUM [A(I,K)'*X(I,L)]}*A(L,L).
-C                    I=1
-C
-C        Start column loop (index = L).
-C        L1 (L2): column index of the first (last) row of X(K,L).
-C
-         LNEXT = 1
-C
-         DO 60 L = 1, N
-            IF( L.LT.LNEXT )
-     $         GO TO 60
-            L1 = L
-            L2 = L
-            IF( L.LT.N ) THEN
-               IF( A( L+1, L ).NE.ZERO )
-     $            L2 = L2 + 1
-               LNEXT = L2 + 1
-            END IF
-C
-C           Start row loop (index = K).
-C           K1 (K2): row index of the first (last) row of X(K,L).
-C
-            DWORK( L1 )   = ZERO
-            DWORK( N+L1 ) = ZERO
-            CALL DSYMV( 'Lower', L1-1, ONE, C, LDC, A( 1, L1 ), 1, ZERO,
-     $                  DWORK, 1 )
-            CALL DSYMV( 'Lower', L1-1, ONE, C, LDC, A( 1, L2 ), 1, ZERO,
-     $                  DWORK( NP1 ), 1 )
-C
-            KNEXT = L
-C
-            DO 50 K = L, N
-               IF( K.LT.KNEXT )
-     $            GO TO 50
-               K1 = K
-               K2 = K
-               IF( K.LT.N ) THEN
-                  IF( A( K+1, K ).NE.ZERO )
-     $               K2 = K2 + 1
-                  KNEXT = K2 + 1
-               END IF
-C
-               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
-                  DWORK( K1 ) = DDOT( L1-1, C( K1, 1 ), LDC, A( 1, L1 ),
-     $                                1 )
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( K1, A( 1, K1 ), 1, DWORK, 1 ) + A( L1, L1 )
-     $                *DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 ) )
-                  SCALOC = ONE
-C
-                  A11 = A( K1, K1 )*A( L1, L1 ) - ONE
-                  DA11 = ABS( A11 )
-                  IF( DA11.LE.SMIN ) THEN
-                     A11 = SMIN
-                     DA11 = SMIN
-                     INFO = 1
-                  END IF
-                  DB = ABS( VEC( 1, 1 ) )
-                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
-                     IF( DB.GT.BIGNUM*DA11 )
-     $                  SCALOC = ONE / DB
-                  END IF
-                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 10 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   10                CONTINUE
-C
-                     CALL DSCAL( N, SCALOC, DWORK, 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  IF( K1.NE.L1 ) THEN
-                     C( L1, K1 ) = X( 1, 1 )
-                  END IF
-C
-               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
-C
-                  DWORK( K1 ) = DDOT( L1-1, C( K1, 1 ), LDC, A( 1, L1 ),
-     $                                1 )
-                  DWORK( K2 ) = DDOT( L1-1, C( K2, 1 ), LDC, A( 1, L1 ),
-     $                                1 )
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( K2, A( 1, K1 ), 1, DWORK, 1 ) + A( L1, L1 )
-     $                *DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 ) )
-C
-                  VEC( 2, 1 ) = C( K2, L1 ) -
-     $               ( DDOT( K2, A( 1, K2 ), 1, DWORK, 1 ) + A( L1, L1 )
-     $                *DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 ) )
-C
-                  CALL DLALN2( .TRUE., 2, 1, SMIN, A( L1, L1 ),
-     $                         A( K1, K1 ), LDA, ONE, ONE, VEC, 2, ONE,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 20 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   20                CONTINUE
-C
-                     CALL DSCAL( N, SCALOC, DWORK, 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( L1, K1 ) = X( 1, 1 )
-                  C( L1, K2 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  DWORK( K1 ) = DDOT( L1-1, C( K1, 1 ), LDC, A( 1, L1 ),
-     $                                1 )
-                  DWORK( N+K1 ) = DDOT( L1-1, C( K1, 1 ), LDC,
-     $                                  A( 1, L2 ), 1 )
-                  P11 = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
-                  P12 = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( K1, A( 1, K1 ), 1, DWORK, 1 ) +
-     $                 P11*A( L1, L1 ) + P12*A( L2, L1 ) )
-C
-                  VEC( 2, 1 ) = C( K1, L2 ) -
-     $               ( DDOT( K1, A( 1, K1 ), 1, DWORK( NP1 ), 1 ) +
-     $                 P11*A( L1, L2 ) + P12*A( L2, L2 ) )
-C
-                  CALL DLALN2( .TRUE., 2, 1, SMIN, A( K1, K1 ),
-     $                         A( L1, L1 ), LDA, ONE, ONE, VEC, 2, ONE,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 30 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   30                CONTINUE
-C
-                     CALL DSCAL( N, SCALOC, DWORK, 1 )
-                     CALL DSCAL( N, SCALOC, DWORK( NP1 ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 2, 1 )
-                  C( L1, K1 ) = X( 1, 1 )
-                  C( L2, K1 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
-C
-                  DWORK( K1 ) = DDOT( L1-1, C( K1, 1 ), LDC, A( 1, L1 ),
-     $                                1 )
-                  DWORK( K2 ) = DDOT( L1-1, C( K2, 1 ), LDC, A( 1, L1 ),
-     $                                1 )
-                  DWORK( N+K1 ) = DDOT( L1-1, C( K1, 1 ), LDC,
-     $                                  A( 1, L2 ), 1 )
-                  DWORK( N+K2 ) = DDOT( L1-1, C( K2, 1 ), LDC,
-     $                                  A( 1, L2 ), 1 )
-                  P11 = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
-                  P12 = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
-                  P21 = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
-                  P22 = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( K2, A( 1, K1 ), 1, DWORK, 1 ) +
-     $                 P11*A( L1, L1 ) + P12*A( L2, L1 ) )
-C
-                  VEC( 1, 2 ) = C( K1, L2 ) -
-     $               ( DDOT( K2, A( 1, K1 ), 1, DWORK( NP1 ), 1 ) +
-     $                 P11*A( L1, L2 ) + P12*A( L2, L2 ) )
-C
-                  VEC( 2, 1 ) = C( K2, L1 ) -
-     $               ( DDOT( K2, A( 1, K2 ), 1, DWORK, 1 ) +
-     $                 P21*A( L1, L1 ) + P22*A( L2, L1 ) )
-C
-                  VEC( 2, 2 ) = C( K2, L2 ) -
-     $               ( DDOT( K2, A( 1, K2 ), 1, DWORK( NP1 ), 1 ) +
-     $                 P21*A( L1, L2 ) + P22*A( L2, L2 ) )
-C
-                  IF( K1.EQ.L1 ) THEN
-                     CALL SB03MV( .FALSE., LUPPER, A( K1, K1 ), LDA,
-     $                            VEC, 2, SCALOC, X, 2, XNORM, IERR )
-                     IF( LUPPER ) THEN
-                        X( 2, 1 ) = X( 1, 2 )
-                     ELSE
-                        X( 1, 2 ) = X( 2, 1 )
-                     END IF
-                  ELSE
-                     CALL SB04PX( .TRUE., .FALSE., -1, 2, 2,
-     $                            A( K1, K1 ), LDA, A( L1, L1 ), LDA,
-     $                            VEC, 2, SCALOC, X, 2, XNORM, IERR )
-                  END IF
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 40 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   40                CONTINUE
-C
-                     CALL DSCAL( N, SCALOC, DWORK, 1 )
-                     CALL DSCAL( N, SCALOC, DWORK( NP1 ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 1, 2 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( K2, L2 ) = X( 2, 2 )
-                  IF( K1.NE.L1 ) THEN
-                     C( L1, K1 ) = X( 1, 1 )
-                     C( L2, K1 ) = X( 1, 2 )
-                     C( L1, K2 ) = X( 2, 1 )
-                     C( L2, K2 ) = X( 2, 2 )
-                  END IF
-               END IF
-C
-   50       CONTINUE
-C
-   60    CONTINUE
-C
-      ELSE
-C
-C        Solve    A*X*A' - X = scale*C.
-C
-C        The (K,L)th block of X is determined starting from
-C        bottom-right corner column by column by
-C
-C            A(K,K)*X(K,L)*A(L,L)' - X(K,L) = C(K,L) - R(K,L),
-C
-C        where
-C
-C                    N            N
-C          R(K,L) = SUM {A(K,I)* SUM [X(I,J)*A(L,J)']} +
-C                   I=K         J=L+1
-C
-C                      N
-C                   { SUM [A(K,J)*X(J,L)]}*A(L,L)'
-C                    J=K+1
-C
-C        Start column loop (index = L)
-C        L1 (L2): column index of the first (last) row of X(K,L)
-C
-         LNEXT = N
-C
-         DO 120 L = N, 1, -1
-            IF( L.GT.LNEXT )
-     $         GO TO 120
-            L1 = L
-            L2 = L
-            IF( L.GT.1 ) THEN
-               IF( A( L, L-1 ).NE.ZERO ) THEN
-                  L1 = L1 - 1
-                  DWORK( L1 ) = ZERO
-                  DWORK( N+L1 ) = ZERO
-               END IF
-               LNEXT = L1 - 1
-            END IF
-            MINL1N = MIN( L1+1, N )
-            MINL2N = MIN( L2+1, N )
-C
-C           Start row loop (index = K)
-C           K1 (K2): row index of the first (last) row of X(K,L)
-C
-            IF( L2.LT.N ) THEN
-               CALL DSYMV( 'Upper', N-L2, ONE, C( L2+1, L2+1 ), LDC,
-     $                     A( L1, L2+1 ), LDA, ZERO, DWORK( L2+1 ), 1 )
-               CALL DSYMV( 'Upper', N-L2, ONE, C( L2+1, L2+1 ), LDC,
-     $                     A( L2, L2+1 ), LDA, ZERO, DWORK( NP1+L2 ), 1)
-            END IF
-C
-            KNEXT = L
-C
-            DO 110 K = L, 1, -1
-               IF( K.GT.KNEXT )
-     $            GO TO 110
-               K1 = K
-               K2 = K
-               IF( K.GT.1 ) THEN
-                  IF( A( K, K-1 ).NE.ZERO )
-     $               K1 = K1 - 1
-                  KNEXT = K1 - 1
-               END IF
-               MINK1N = MIN( K1+1, N )
-               MINK2N = MIN( K2+1, N )
-C
-               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
-                  DWORK( K1 ) = DDOT( N-L1, C( K1, MINL1N ), LDC,
-     $                                A( L1, MINL1N ), LDA )
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( N-K1+1, A( K1, K1 ), LDA, DWORK( K1 ), 1 )
-     $               + DDOT( N-K1, A( K1, MINK1N ), LDA,
-     $                       C( MINK1N, L1 ), 1 )*A( L1, L1 ) )
-                  SCALOC = ONE
-C
-                  A11 = A( K1, K1 )*A( L1, L1 ) - ONE
-                  DA11 = ABS( A11 )
-                  IF( DA11.LE.SMIN ) THEN
-                     A11 = SMIN
-                     DA11 = SMIN
-                     INFO = 1
-                  END IF
-                  DB = ABS( VEC( 1, 1 ) )
-                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
-                     IF( DB.GT.BIGNUM*DA11 )
-     $                  SCALOC = ONE / DB
-                  END IF
-                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 70 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   70                CONTINUE
-C
-                     CALL DSCAL( N, SCALOC, DWORK, 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  IF( K1.NE.L1 ) THEN
-                     C( L1, K1 ) = X( 1, 1 )
-                  END IF
-C
-               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
-C
-                  DWORK( K1 ) = DDOT( N-L1, C( K1, MINL1N ), LDC,
-     $                                A( L1, MINL1N ), LDA )
-                  DWORK( K2 ) = DDOT( N-L1, C( K2, MINL1N ), LDC,
-     $                                A( L1, MINL1N ), LDA )
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( NP1-K1, A( K1, K1 ), LDA, DWORK( K1 ), 1 )
-     $               + DDOT( N-K2, A( K1, MINK2N ), LDA,
-     $                       C( MINK2N, L1 ), 1 )*A( L1, L1 ) )
-C
-                  VEC( 2, 1 ) = C( K2, L1 ) -
-     $               ( DDOT( NP1-K1, A( K2, K1 ), LDA, DWORK( K1 ), 1 )
-     $               + DDOT( N-K2, A( K2, MINK2N ), LDA,
-     $                       C( MINK2N, L1 ), 1 )*A( L1, L1 ) )
-C
-                  CALL DLALN2( .FALSE., 2, 1, SMIN, A( L1, L1 ),
-     $                         A( K1, K1 ), LDA, ONE, ONE, VEC, 2, ONE,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 80 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   80                CONTINUE
-C
-                     CALL DSCAL( N, SCALOC, DWORK, 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( L1, K1 ) = X( 1, 1 )
-                  C( L1, K2 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  DWORK( K1 ) = DDOT( N-L2, C( K1, MINL2N ), LDC,
-     $                                A( L1, MINL2N ), LDA )
-                  DWORK( N+K1 ) = DDOT( N-L2, C( K1, MINL2N ), LDC,
-     $                                  A( L2, MINL2N ), LDA )
-                  P11 = DDOT( N-K1, A( K1, MINK1N ), LDA,
-     $                        C( MINK1N, L1 ), 1 )
-                  P12 = DDOT( N-K1, A( K1, MINK1N ), LDA,
-     $                        C( MINK1N, L2 ), 1 )
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( NP1-K1, A( K1, K1 ), LDA, DWORK( K1 ), 1 )
-     $               + P11*A( L1, L1 ) + P12*A( L1, L2 ) )
-C
-                  VEC( 2, 1 ) = C( K1, L2 ) -
-     $               ( DDOT( NP1-K1, A( K1, K1 ), LDA, DWORK( N+K1 ), 1)
-     $               + P11*A( L2, L1 ) + P12*A( L2, L2 ) )
-C
-                  CALL DLALN2( .FALSE., 2, 1, SMIN, A( K1, K1 ),
-     $                         A( L1, L1 ), LDA, ONE, ONE, VEC, 2, ONE,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 90 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   90                CONTINUE
-C
-                     CALL DSCAL( N, SCALOC, DWORK, 1 )
-                     CALL DSCAL( N, SCALOC, DWORK( NP1 ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 2, 1 )
-                  C( L1, K1 ) = X( 1, 1 )
-                  C( L2, K1 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
-C
-                  DWORK( K1 ) = DDOT( N-L2, C( K1, MINL2N ), LDC,
-     $                                A( L1, MINL2N ), LDA )
-                  DWORK( K2 ) = DDOT( N-L2, C( K2, MINL2N ), LDC,
-     $                                A( L1, MINL2N ), LDA )
-                  DWORK( N+K1 ) = DDOT( N-L2, C( K1, MINL2N ), LDC,
-     $                                  A( L2, MINL2N ), LDA )
-                  DWORK( N+K2 ) = DDOT( N-L2, C( K2, MINL2N ), LDC,
-     $                                  A( L2, MINL2N ), LDA )
-                  P11 = DDOT( N-K2, A( K1, MINK2N ), LDA,
-     $                        C( MINK2N, L1 ), 1 )
-                  P12 = DDOT( N-K2, A( K1, MINK2N ), LDA,
-     $                        C( MINK2N, L2 ), 1 )
-                  P21 = DDOT( N-K2, A( K2, MINK2N ), LDA,
-     $                        C( MINK2N, L1 ), 1 )
-                  P22 = DDOT( N-K2, A( K2, MINK2N ), LDA,
-     $                        C( MINK2N, L2 ), 1 )
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( NP1-K1, A( K1, K1 ), LDA, DWORK( K1 ), 1 )
-     $               + P11*A( L1, L1 ) + P12*A( L1, L2 ) )
-C
-                  VEC( 1, 2 ) = C( K1, L2 ) -
-     $               ( DDOT( NP1-K1, A( K1, K1 ), LDA, DWORK( N+K1 ),
-     $                       1) + P11*A( L2, L1 ) + P12*A( L2, L2 ) )
-C
-                  VEC( 2, 1 ) = C( K2, L1 ) -
-     $               ( DDOT( NP1-K1, A( K2, K1 ), LDA, DWORK( K1 ),
-     $                       1) + P21*A( L1, L1 ) + P22*A( L1, L2 ) )
-C
-                  VEC( 2, 2 ) = C( K2, L2 ) -
-     $               ( DDOT( NP1-K1, A( K2, K1 ), LDA, DWORK( N+K1 ), 1)
-     $               + P21*A( L2, L1 ) + P22*A( L2, L2 ) )
-C
-                  IF( K1.EQ.L1 ) THEN
-                     CALL SB03MV( .TRUE., LUPPER, A( K1, K1 ), LDA, VEC,
-     $                            2, SCALOC, X, 2, XNORM, IERR )
-                     IF( LUPPER ) THEN
-                        X( 2, 1 ) = X( 1, 2 )
-                     ELSE
-                        X( 1, 2 ) = X( 2, 1 )
-                     END IF
-                  ELSE
-                     CALL SB04PX( .FALSE., .TRUE., -1, 2, 2,
-     $                            A( K1, K1 ), LDA, A( L1, L1 ), LDA,
-     $                            VEC, 2, SCALOC, X, 2, XNORM, IERR )
-                  END IF
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 100 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-  100                CONTINUE
-C
-                     CALL DSCAL( N, SCALOC, DWORK, 1 )
-                     CALL DSCAL( N, SCALOC, DWORK( NP1 ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 1, 2 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( K2, L2 ) = X( 2, 2 )
-                  IF( K1.NE.L1 ) THEN
-                     C( L1, K1 ) = X( 1, 1 )
-                     C( L2, K1 ) = X( 1, 2 )
-                     C( L1, K2 ) = X( 2, 1 )
-                     C( L2, K2 ) = X( 2, 2 )
-                  END IF
-               END IF
-C
-  110       CONTINUE
-C
-  120    CONTINUE
-C
-      END IF
-C
-      RETURN
-C *** Last line of SB03MX ***
-      END
--- a/extra/control-devel/src/SB03MY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,613 +0,0 @@
-      SUBROUTINE SB03MY( TRANA, N, A, LDA, C, LDC, SCALE, 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 the real Lyapunov matrix equation
-C
-C            op(A)'*X + X*op(A) = scale*C
-C
-C     where op(A) = A or A' (A**T), A is upper quasi-triangular and C is
-C     symmetric (C = C'). (A' denotes the transpose of the matrix A.)
-C     A is N-by-N, the right hand side C and the solution X are N-by-N,
-C     and scale is an output scale factor, set less than or equal to 1
-C     to avoid overflow in X. The solution matrix X is overwritten
-C     onto C.
-C
-C     A must be in Schur canonical form (as returned by LAPACK routines
-C     DGEES or DHSEQR), that is, block upper triangular with 1-by-1 and
-C     2-by-2 diagonal blocks; each 2-by-2 diagonal block has its
-C     diagonal elements equal and its off-diagonal elements of opposite
-C     sign.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A, X, and C.  N >= 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             upper quasi-triangular matrix A, in Schur canonical form.
-C             The part of A below the first sub-diagonal is not
-C             referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the symmetric matrix C.
-C             On exit, if INFO >= 0, the leading N-by-N part of this
-C             array contains the symmetric solution matrix X.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,N).
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor, scale, set less than or equal to 1 to
-C             prevent the solution overflowing.
-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 A and -A have common or very close eigenvalues;
-C                   perturbed values were used to solve the equation
-C                   (but the matrix A is unchanged).
-C
-C     METHOD
-C
-C     Bartels-Stewart algorithm is used. A set of equivalent linear
-C     algebraic systems of equations of order at most four are formed
-C     and solved using Gaussian elimination with complete pivoting.
-C
-C     REFERENCES
-C
-C     [1] Bartels, R.H. and Stewart, G.W.  T
-C         Solution of the matrix equation A X + XB = C.
-C         Comm. A.C.M., 15, pp. 820-826, 1972.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, May 1997.
-C     Supersedes Release 2.0 routine SB03AY by Control Systems Research
-C     Group, Kingston Polytechnic, United Kingdom, October 1982.
-C     Based on DTRLYP by P. Petkov, Tech. University of Sofia, September
-C     1993.
-C
-C     REVISIONS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, May 1999.
-C
-C     KEYWORDS
-C
-C     Continuous-time system, Lyapunov equation, matrix algebra, real
-C     Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          TRANA
-      INTEGER            INFO, LDA, LDC, N
-      DOUBLE PRECISION   SCALE
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A( LDA, * ), C( LDC, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            NOTRNA, LUPPER
-      INTEGER            IERR, J, K, K1, K2, KNEXT, L, L1, L2, LNEXT,
-     $                   MINK1N, MINK2N, MINL1N, MINL2N
-      DOUBLE PRECISION   A11, BIGNUM, DA11, DB, EPS, SCALOC, SMIN,
-     $                   SMLNUM, XNORM
-C     ..
-C     .. Local Arrays ..
-      DOUBLE PRECISION   DUM( 1 ), VEC( 2, 2 ), X( 2, 2 )
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DDOT, DLAMCH, DLANHS
-      EXTERNAL           DDOT, DLAMCH, DLANHS, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DLABAD, DLALN2, DLASY2, DSCAL, SB03MW, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, DBLE, MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode and Test input parameters.
-C
-      NOTRNA = LSAME( TRANA, 'N' )
-      LUPPER = .TRUE.
-C
-      INFO = 0
-      IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'T' ) .AND.
-     $                      .NOT.LSAME( TRANA, 'C' ) ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -4
-      ELSE IF( LDC.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'SB03MY', -INFO )
-         RETURN
-      END IF
-C
-      SCALE = ONE
-C
-C     Quick return if possible.
-C
-      IF( N.EQ.0 )
-     $   RETURN
-C
-C     Set constants to control overflow.
-C
-      EPS = DLAMCH( 'P' )
-      SMLNUM = DLAMCH( 'S' )
-      BIGNUM = ONE / SMLNUM
-      CALL DLABAD( SMLNUM, BIGNUM )
-      SMLNUM = SMLNUM*DBLE( N*N ) / EPS
-      BIGNUM = ONE / SMLNUM
-C
-      SMIN = MAX( SMLNUM, EPS*DLANHS( 'Max', N, A, LDA, DUM ) )
-C
-      IF( NOTRNA ) THEN
-C
-C        Solve    A'*X + X*A = scale*C.
-C
-C        The (K,L)th block of X is determined starting from
-C        upper-left corner column by column by
-C
-C          A(K,K)'*X(K,L) + X(K,L)*A(L,L) = C(K,L) - R(K,L),
-C
-C        where
-C                   K-1                    L-1
-C          R(K,L) = SUM [A(I,K)'*X(I,L)] + SUM [X(K,J)*A(J,L)].
-C                   I=1                    J=1
-C
-C        Start column loop (index = L).
-C        L1 (L2): column index of the first (last) row of X(K,L).
-C
-         LNEXT = 1
-C
-         DO 60 L = 1, N
-            IF( L.LT.LNEXT )
-     $         GO TO 60
-            L1 = L
-            L2 = L
-            IF( L.LT.N ) THEN
-               IF( A( L+1, L ).NE.ZERO )
-     $            L2 = L2 + 1
-               LNEXT = L2 + 1
-            END IF
-C
-C           Start row loop (index = K).
-C           K1 (K2): row index of the first (last) row of X(K,L).
-C
-            KNEXT = L
-C
-            DO 50 K = L, N
-               IF( K.LT.KNEXT )
-     $            GO TO 50
-               K1 = K
-               K2 = K
-               IF( K.LT.N ) THEN
-                  IF( A( K+1, K ).NE.ZERO )
-     $               K2 = K2 + 1
-                  KNEXT = K2 + 1
-               END IF
-C
-               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 ) +
-     $                 DDOT( L1-1, C( K1, 1 ), LDC, A( 1, L1 ), 1 ) )
-                  SCALOC = ONE
-C
-                  A11 = A( K1, K1 ) + A( L1, L1 )
-                  DA11 = ABS( A11 )
-                  IF( DA11.LE.SMIN ) THEN
-                     A11 = SMIN
-                     DA11 = SMIN
-                     INFO = 1
-                  END IF
-                  DB = ABS( VEC( 1, 1 ) )
-                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
-                     IF( DB.GT.BIGNUM*DA11 )
-     $                  SCALOC = ONE / DB
-                  END IF
-                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 10 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   10                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  IF( K1.NE.L1 ) THEN
-                     C( L1, K1 ) = X( 1, 1 )
-                  END IF
-C
-               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 ) +
-     $                 DDOT( L1-1, C( K1, 1 ), LDC, A( 1, L1 ), 1 ) )
-C
-                  VEC( 2, 1 ) = C( K2, L1 ) -
-     $               ( DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 ) +
-     $                 DDOT( L1-1, C( K2, 1 ), LDC, A( 1, L1 ), 1 ) )
-C
-                  CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, A( K1, K1 ),
-     $                         LDA, ONE, ONE, VEC, 2, -A( L1, L1 ),
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 20 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   20                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( L1, K1 ) = X( 1, 1 )
-                  C( L1, K2 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 ) +
-     $                 DDOT( L1-1, C( K1, 1 ), LDC, A( 1, L1 ), 1 ) )
-C
-                  VEC( 2, 1 ) = C( K1, L2 ) -
-     $               ( DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 ) +
-     $                 DDOT( L1-1, C( K1, 1 ), LDC, A( 1, L2 ), 1 ) )
-C
-                  CALL DLALN2( .TRUE., 2, 1, SMIN, ONE, A( L1, L1 ),
-     $                         LDA, ONE, ONE, VEC, 2, -A( K1, K1 ),
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 30 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   30                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 2, 1 )
-                  C( L1, K1 ) = X( 1, 1 )
-                  C( L2, K1 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 ) +
-     $                 DDOT( L1-1, C( K1, 1 ), LDC, A( 1, L1 ), 1 ) )
-C
-                  VEC( 1, 2 ) = C( K1, L2 ) -
-     $               ( DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 ) +
-     $                 DDOT( L1-1, C( K1, 1 ), LDC, A( 1, L2 ), 1 ) )
-C
-                  VEC( 2, 1 ) = C( K2, L1 ) -
-     $               ( DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 ) +
-     $                 DDOT( L1-1, C( K2, 1 ), LDC, A( 1, L1 ), 1 ) )
-C
-                  VEC( 2, 2 ) = C( K2, L2 ) -
-     $               ( DDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 ) +
-     $                 DDOT( L1-1, C( K2, 1 ), LDC, A( 1, L2 ), 1 ) )
-C
-                  IF( K1.EQ.L1 ) THEN
-                     CALL SB03MW( .FALSE., LUPPER, A( K1, K1 ), LDA,
-     $                            VEC, 2, SCALOC, X, 2, XNORM, IERR )
-                     IF( LUPPER ) THEN
-                        X( 2, 1 ) = X( 1, 2 )
-                     ELSE
-                        X( 1, 2 ) = X( 2, 1 )
-                     END IF
-                  ELSE
-                     CALL DLASY2( .TRUE., .FALSE., 1, 2, 2, A( K1, K1 ),
-     $                            LDA, A( L1, L1 ), LDA, VEC, 2, SCALOC,
-     $                            X, 2, XNORM, IERR )
-                  END IF
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 40 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   40                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 1, 2 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( K2, L2 ) = X( 2, 2 )
-                  IF( K1.NE.L1 ) THEN
-                     C( L1, K1 ) = X( 1, 1 )
-                     C( L2, K1 ) = X( 1, 2 )
-                     C( L1, K2 ) = X( 2, 1 )
-                     C( L2, K2 ) = X( 2, 2 )
-                  END IF
-               END IF
-C
-   50       CONTINUE
-C
-   60    CONTINUE
-C
-      ELSE
-C
-C        Solve    A*X + X*A' = scale*C.
-C
-C        The (K,L)th block of X is determined starting from
-C        bottom-right corner column by column by
-C
-C            A(K,K)*X(K,L) + X(K,L)*A(L,L)' = C(K,L) - R(K,L),
-C
-C        where
-C                      N                     N
-C            R(K,L) = SUM [A(K,I)*X(I,L)] + SUM [X(K,J)*A(L,J)'].
-C                    I=K+1                 J=L+1
-C
-C        Start column loop (index = L).
-C        L1 (L2): column index of the first (last) row of X(K,L).
-C
-         LNEXT = N
-C
-         DO 120 L = N, 1, -1
-            IF( L.GT.LNEXT )
-     $         GO TO 120
-            L1 = L
-            L2 = L
-            IF( L.GT.1 ) THEN
-               IF( A( L, L-1 ).NE.ZERO )
-     $            L1 = L1 - 1
-               LNEXT = L1 - 1
-            END IF
-            MINL1N = MIN( L1+1, N )
-            MINL2N = MIN( L2+1, N )
-C
-C           Start row loop (index = K).
-C           K1 (K2): row index of the first (last) row of X(K,L).
-C
-            KNEXT = L
-C
-            DO 110 K = L, 1, -1
-               IF( K.GT.KNEXT )
-     $            GO TO 110
-               K1 = K
-               K2 = K
-               IF( K.GT.1 ) THEN
-                  IF( A( K, K-1 ).NE.ZERO )
-     $               K1 = K1 - 1
-                  KNEXT = K1 - 1
-               END IF
-               MINK1N = MIN( K1+1, N )
-               MINK2N = MIN( K2+1, N )
-C
-               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( N-K1, A( K1, MINK1N ), LDA,
-     $                       C( MINK1N, L1 ), 1 ) +
-     $                 DDOT( N-L1, C( K1, MINL1N ), LDC,
-     $                       A( L1, MINL1N ), LDA ) )
-                  SCALOC = ONE
-C
-                  A11 = A( K1, K1 ) + A( L1, L1 )
-                  DA11 = ABS( A11 )
-                  IF( DA11.LE.SMIN ) THEN
-                     A11 = SMIN
-                     DA11 = SMIN
-                     INFO = 1
-                  END IF
-                  DB = ABS( VEC( 1, 1 ) )
-                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
-                     IF( DB.GT.BIGNUM*DA11 )
-     $                  SCALOC = ONE / DB
-                  END IF
-                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 70 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   70                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  IF( K1.NE.L1 ) THEN
-                     C( L1, K1 ) = X( 1, 1 )
-                  END IF
-C
-               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( N-K2, A( K1, MINK2N ), LDA,
-     $                       C( MINK2N, L1 ), 1 ) +
-     $                 DDOT( N-L2, C( K1, MINL2N ), LDC,
-     $                       A( L1, MINL2N ), LDA ) )
-C
-                  VEC( 2, 1 ) = C( K2, L1 ) -
-     $               ( DDOT( N-K2, A( K2, MINK2N ), LDA,
-     $                     C( MINK2N, L1 ), 1 ) +
-     $                 DDOT( N-L2, C( K2, MINL2N ), LDC,
-     $                     A( L1, MINL2N ), LDA ) )
-C
-                  CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, A( K1, K1 ),
-     $                         LDA, ONE, ONE, VEC, 2, -A( L1, L1 ),
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 80 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   80                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( L1, K1 ) = X( 1, 1 )
-                  C( L1, K2 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( N-K1, A( K1, MINK1N ), LDA,
-     $                       C( MINK1N, L1 ), 1 ) +
-     $                 DDOT( N-L2, C( K1, MINL2N ), LDC,
-     $                       A( L1, MINL2N ), LDA ) )
-C
-                  VEC( 2, 1 ) = C( K1, L2 ) -
-     $               ( DDOT( N-K1, A( K1, MINK1N ), LDA,
-     $                       C( MINK1N, L2 ), 1 ) +
-     $                 DDOT( N-L2, C( K1, MINL2N ), LDC,
-     $                       A( L2, MINL2N ), LDA ) )
-C
-                  CALL DLALN2( .FALSE., 2, 1, SMIN, ONE, A( L1, L1 ),
-     $                         LDA, ONE, ONE, VEC, 2, -A( K1, K1 ),
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 90 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   90                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 2, 1 )
-                  C( L1, K1 ) = X( 1, 1 )
-                  C( L2, K1 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
-C
-                  VEC( 1, 1 ) = C( K1, L1 ) -
-     $               ( DDOT( N-K2, A( K1, MINK2N ), LDA,
-     $                       C( MINK2N, L1 ), 1 ) +
-     $                 DDOT( N-L2, C( K1, MINL2N ), LDC,
-     $                       A( L1, MINL2N ), LDA ) )
-C
-                  VEC( 1, 2 ) = C( K1, L2 ) -
-     $               ( DDOT( N-K2, A( K1, MINK2N ), LDA,
-     $                       C( MINK2N, L2 ), 1 ) +
-     $                 DDOT( N-L2, C( K1, MINL2N ), LDC,
-     $                       A( L2, MINL2N ), LDA ) )
-C
-                  VEC( 2, 1 ) = C( K2, L1 ) -
-     $               ( DDOT( N-K2, A( K2, MINK2N ), LDA,
-     $                       C( MINK2N, L1 ), 1 ) +
-     $                 DDOT( N-L2, C( K2, MINL2N ), LDC,
-     $                       A( L1, MINL2N ), LDA ) )
-C
-                  VEC( 2, 2 ) = C( K2, L2 ) -
-     $               ( DDOT( N-K2, A( K2, MINK2N ), LDA,
-     $                       C( MINK2N, L2 ), 1 ) +
-     $                 DDOT( N-L2, C( K2, MINL2N ), LDC,
-     $                       A( L2, MINL2N ), LDA ) )
-C
-                  IF( K1.EQ.L1 ) THEN
-                     CALL SB03MW( .TRUE., LUPPER, A( K1, K1 ), LDA, VEC,
-     $                            2, SCALOC, X, 2, XNORM, IERR )
-                     IF( LUPPER ) THEN
-                        X( 2, 1 ) = X( 1, 2 )
-                     ELSE
-                        X( 1, 2 ) = X( 2, 1 )
-                     END IF
-                  ELSE
-                     CALL DLASY2( .FALSE., .TRUE., 1, 2, 2, A( K1, K1 ),
-     $                            LDA, A( L1, L1 ), LDA, VEC, 2, SCALOC,
-     $                            X, 2, XNORM, IERR )
-                  END IF
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 100 J = 1, N
-                        CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-  100                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 1, 2 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( K2, L2 ) = X( 2, 2 )
-                  IF( K1.NE.L1 ) THEN
-                     C( L1, K1 ) = X( 1, 1 )
-                     C( L2, K1 ) = X( 1, 2 )
-                     C( L1, K2 ) = X( 2, 1 )
-                     C( L2, K2 ) = X( 2, 2 )
-                  END IF
-               END IF
-C
-  110       CONTINUE
-C
-  120    CONTINUE
-C
-      END IF
-C
-      RETURN
-C *** Last line of SB03MY ***
-      END
--- a/extra/control-devel/src/SB03OD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,662 +0,0 @@
-      SUBROUTINE SB03OD( DICO, FACT, TRANS, N, M, A, LDA, Q, LDQ, B,
-     $                   LDB, SCALE, WR, WI, DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To solve for X = op(U)'*op(U) either the stable non-negative
-C     definite continuous-time Lyapunov equation
-C                                   2
-C        op(A)'*X + X*op(A) = -scale *op(B)'*op(B)                   (1)
-C
-C     or the convergent non-negative definite discrete-time Lyapunov
-C     equation
-C                                   2
-C        op(A)'*X*op(A) - X = -scale *op(B)'*op(B)                   (2)
-C
-C     where op(K) = K or K' (i.e., the transpose of the matrix K), A is
-C     an N-by-N matrix, op(B) is an M-by-N matrix, U is an upper
-C     triangular matrix containing the Cholesky factor of the solution
-C     matrix X, X = op(U)'*op(U), and scale is an output scale factor,
-C     set less than or equal to 1 to avoid overflow in X. If matrix B
-C     has full rank then the solution matrix X will be positive-definite
-C     and hence the Cholesky factor U will be nonsingular, but if B is
-C     rank deficient then X may be only positive semi-definite and U
-C     will be singular.
-C
-C     In the case of equation (1) the matrix A must be stable (that
-C     is, all the eigenvalues of A must have negative real parts),
-C     and for equation (2) the matrix A must be convergent (that is,
-C     all the eigenvalues of A must lie inside the unit circle).
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of Lyapunov equation to be solved as
-C             follows:
-C             = 'C':  Equation (1), continuous-time case;
-C             = 'D':  Equation (2), discrete-time case.
-C
-C     FACT    CHARACTER*1
-C             Specifies whether or not the real Schur factorization
-C             of the matrix A is supplied on entry, as follows:
-C             = 'F':  On entry, A and Q contain the factors from the
-C                     real Schur factorization of the matrix A;
-C             = 'N':  The Schur factorization of A will be computed
-C                     and the factors will be stored in A and Q.
-C
-C     TRANS   CHARACTER*1
-C             Specifies the form of op(K) to be used, as follows:
-C             = 'N':  op(K) = K    (No transpose);
-C             = 'T':  op(K) = K**T (Transpose).
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix A and the number of columns in
-C             matrix op(B).  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of rows in matrix op(B).  M >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the matrix A. If FACT = 'F', then A contains
-C             an upper quasi-triangular matrix S in Schur canonical
-C             form; the elements below the upper Hessenberg part of the
-C             array A are not referenced.
-C             On exit, the leading N-by-N upper Hessenberg part of this
-C             array contains the upper quasi-triangular matrix S in
-C             Schur canonical form from the Shur factorization of A.
-C             The contents of array A is not modified if FACT = 'F'.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     Q       (input or output) DOUBLE PRECISION array, dimension
-C             (LDQ,N)
-C             On entry, if FACT = 'F', then the leading N-by-N part of
-C             this array must contain the orthogonal matrix Q of the
-C             Schur factorization of A.
-C             Otherwise, Q need not be set on entry.
-C             On exit, the leading N-by-N part of this array contains
-C             the orthogonal matrix Q of the Schur factorization of A.
-C             The contents of array Q is not modified if FACT = 'F'.
-C
-C     LDQ     INTEGER
-C             The leading dimension of array Q.  LDQ >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,N)
-C             if TRANS = 'N', and dimension (LDB,max(M,N)), if
-C             TRANS = 'T'.
-C             On entry, if TRANS = 'N', the leading M-by-N part of this
-C             array must contain the coefficient matrix B of the
-C             equation.
-C             On entry, if TRANS = 'T', the leading N-by-M part of this
-C             array must contain the coefficient matrix B of the
-C             equation.
-C             On exit, the leading N-by-N part of this array contains
-C             the upper triangular Cholesky factor U of the solution
-C             matrix X of the problem, X = op(U)'*op(U).
-C             If M = 0 and N > 0, then U is set to zero.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.
-C             LDB >= MAX(1,N,M), if TRANS = 'N';
-C             LDB >= MAX(1,N),   if TRANS = 'T'.
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor, scale, set less than or equal to 1 to
-C             prevent the solution overflowing.
-C
-C     WR      (output) DOUBLE PRECISION array, dimension (N)
-C     WI      (output) DOUBLE PRECISION array, dimension (N)
-C             If FACT = 'N', and INFO >= 0 and INFO <= 2, WR and WI
-C             contain the real and imaginary parts, respectively, of
-C             the eigenvalues of A.
-C             If FACT = 'F', WR and WI are not referenced.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, or INFO = 1, DWORK(1) returns the
-C             optimal value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             If M > 0, LDWORK >= MAX(1,4*N + MIN(M,N));
-C             If M = 0, LDWORK >= 1.
-C             For optimum performance LDWORK should sometimes 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 Lyapunov equation is (nearly) singular
-C                   (warning indicator);
-C                   if DICO = 'C' this means that while the matrix A
-C                   (or the factor S) has computed eigenvalues with
-C                   negative real parts, it is only just stable in the
-C                   sense that small perturbations in A can make one or
-C                   more of the eigenvalues have a non-negative real
-C                   part;
-C                   if DICO = 'D' this means that while the matrix A
-C                   (or the factor S) has computed eigenvalues inside
-C                   the unit circle, it is nevertheless only just
-C                   convergent, in the sense that small perturbations
-C                   in A can make one or more of the eigenvalues lie
-C                   outside the unit circle;
-C                   perturbed values were used to solve the equation;
-C             = 2:  if FACT = 'N' and DICO = 'C', but the matrix A is
-C                   not stable (that is, one or more of the eigenvalues
-C                   of A has a non-negative real part), or DICO = 'D',
-C                   but the matrix A is not convergent (that is, one or
-C                   more of the eigenvalues of A lies outside the unit
-C                   circle); however, A will still have been factored
-C                   and the eigenvalues of A returned in WR and WI.
-C             = 3:  if FACT = 'F' and DICO = 'C', but the Schur factor S
-C                   supplied in the array A is not stable (that is, one
-C                   or more of the eigenvalues of S has a non-negative
-C                   real part), or DICO = 'D', but the Schur factor S
-C                   supplied in the array A is not convergent (that is,
-C                   one or more of the eigenvalues of S lies outside the
-C                   unit circle);
-C             = 4:  if FACT = 'F' and the Schur factor S supplied in
-C                   the array A has two or more consecutive non-zero
-C                   elements on the first sub-diagonal, so that there is
-C                   a block larger than 2-by-2 on the diagonal;
-C             = 5:  if FACT = 'F' and the Schur factor S supplied in
-C                   the array A has a 2-by-2 diagonal block with real
-C                   eigenvalues instead of a complex conjugate pair;
-C             = 6:  if FACT = 'N' and the LAPACK Library routine DGEES
-C                   has failed to converge. This failure is not likely
-C                   to occur. The matrix B will be unaltered but A will
-C                   be destroyed.
-C
-C     METHOD
-C
-C     The method used by the routine is based on the Bartels and Stewart
-C     method [1], except that it finds the upper triangular matrix U
-C     directly without first finding X and without the need to form the
-C     normal matrix op(B)'*op(B).
-C
-C     The Schur factorization of a square matrix A is given by
-C
-C        A = QSQ',
-C
-C     where Q is orthogonal and S is an N-by-N block upper triangular
-C     matrix with 1-by-1 and 2-by-2 blocks on its diagonal (which
-C     correspond to the eigenvalues of A). If A has already been
-C     factored prior to calling the routine however, then the factors
-C     Q and S may be supplied and the initial factorization omitted.
-C
-C     If TRANS = 'N', the matrix B is factored as (QR factorization)
-C            _   _                   _   _  _
-C        B = P ( R ),  M >= N,   B = P ( R  Z ),  M < N,
-C              ( 0 )
-C           _                                    _
-C     where P is an M-by-M orthogonal matrix and R is a square upper
-C                                         _   _      _     _  _
-C     triangular matrix. Then, the matrix B = RQ, or B = ( R  Z )Q (if
-C     M < N) is factored as
-C        _                       _
-C        B = P ( R ),  M >= N,   B = P ( R  Z ),  M < N.
-C
-C     If TRANS = 'T', the matrix B is factored as (RQ factorization)
-C                                         _
-C                 _   _                 ( Z ) _
-C        B = ( 0  R ) P,  M >= N,   B = ( _ ) P,  M < N,
-C                                       ( R )
-C           _                                    _
-C     where P is an M-by-M orthogonal matrix and R is a square upper
-C                                         _     _     _       _   _
-C     triangular matrix. Then, the matrix B = Q'R, or B = Q'( Z'  R' )'
-C     (if M < N) is factored as
-C        _                       _
-C        B = ( R ) P,  M >= N,   B = ( Z ) P,  M < N.
-C                                    ( R )
-C
-C     These factorizations are utilised to either transform the
-C     continuous-time Lyapunov equation to the canonical form
-C                                                        2
-C       op(S)'*op(V)'*op(V) + op(V)'*op(V)*op(S) = -scale *op(F)'*op(F),
-C
-C     or the discrete-time Lyapunov equation to the canonical form
-C                                                        2
-C       op(S)'*op(V)'*op(V)*op(S) - op(V)'*op(V) = -scale *op(F)'*op(F),
-C
-C     where V and F are upper triangular, and
-C
-C        F = R,  M >= N,   F = ( R  Z ),  M < N, if TRANS = 'N';
-C                              ( 0  0 )
-C
-C        F = R,  M >= N,   F = ( 0  Z ),  M < N, if TRANS = 'T'.
-C                              ( 0  R )
-C
-C     The transformed equation is then solved for V, from which U is
-C     obtained via the QR factorization of V*Q', if TRANS = 'N', or
-C     via the RQ factorization of Q*V, if TRANS = 'T'.
-C
-C     REFERENCES
-C
-C     [1] Bartels, R.H. and Stewart, G.W.
-C         Solution of the matrix equation  A'X + XB = C.
-C         Comm. A.C.M., 15, pp. 820-826, 1972.
-C
-C     [2] Hammarling, S.J.
-C         Numerical solution of the stable, non-negative definite
-C         Lyapunov equation.
-C         IMA J. Num. Anal., 2, pp. 303-325, 1982.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations and is backward stable.
-C
-C     FURTHER COMMENTS
-C
-C     The Lyapunov equation may be very ill-conditioned. In particular,
-C     if A is only just stable (or convergent) then the Lyapunov
-C     equation will be ill-conditioned.  A symptom of ill-conditioning
-C     is "large" elements in U relative to those of A and B, or a
-C     "small" value for scale. A condition estimate can be computed
-C     using SLICOT Library routine SB03MD.
-C
-C     SB03OD routine can be also used for solving "unstable" Lyapunov
-C     equations, i.e., when matrix A has all eigenvalues with positive
-C     real parts, if DICO = 'C', or with moduli greater than one,
-C     if DICO = 'D'. Specifically, one may solve for X = op(U)'*op(U)
-C     either the continuous-time Lyapunov equation
-C                                  2
-C        op(A)'*X + X*op(A) = scale *op(B)'*op(B),                   (3)
-C
-C     or the discrete-time Lyapunov equation
-C                                  2
-C        op(A)'*X*op(A) - X = scale *op(B)'*op(B),                   (4)
-C
-C     provided, for equation (3), the given matrix A is replaced by -A,
-C     or, for equation (4), the given matrices A and B are replaced by
-C     inv(A) and B*inv(A), if TRANS = 'N' (or inv(A)*B, if TRANS = 'T'),
-C     respectively. Although the inversion generally can rise numerical
-C     problems, in case of equation (4) it is expected that the matrix A
-C     is enough well-conditioned, having only eigenvalues with moduli
-C     greater than 1. However, if A is ill-conditioned, it could be
-C     preferable to use the more general SLICOT Lyapunov solver SB03MD.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Aug. 1997.
-C     Supersedes Release 2.0 routine SB03CD by Sven Hammarling,
-C     NAG Ltd, United Kingdom.
-C
-C     REVISIONS
-C
-C     Dec. 1997, April 1998, May 1998, May 1999, Oct. 2001 (V. Sima).
-C     March 2002 (A. Varga).
-C
-C     KEYWORDS
-C
-C     Lyapunov equation, orthogonal transformation, real Schur form,
-C     Sylvester equation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, FACT, TRANS
-      INTEGER           INFO, LDA, LDB, LDQ, LDWORK, M, N
-      DOUBLE PRECISION  SCALE
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), DWORK(*), Q(LDQ,*), WI(*),
-     $                  WR(*)
-C     .. Local Scalars ..
-      LOGICAL           CONT, LTRANS, NOFACT
-      INTEGER           I, IFAIL, INFORM, ITAU, J, JWORK, K, L, MINMN,
-     $                  NE, SDIM, WRKOPT
-      DOUBLE PRECISION  EMAX, TEMP
-C     .. Local Arrays ..
-      LOGICAL           BWORK(1)
-C     .. External Functions ..
-      LOGICAL           LSAME, SELECT
-      DOUBLE PRECISION  DLAPY2
-      EXTERNAL          DLAPY2, LSAME, SELECT
-C     .. External Subroutines ..
-      EXTERNAL          DCOPY, DGEES, DGEMM, DGEMV, DGEQRF, DGERQF,
-     $                  DLACPY, DLASET, DTRMM, SB03OU, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         INT, MAX, MIN
-C     .. Executable Statements ..
-C
-C     Test the input scalar arguments.
-C
-      CONT   = LSAME( DICO,  'C' )
-      NOFACT = LSAME( FACT,  'N' )
-      LTRANS = LSAME( TRANS, 'T' )
-      MINMN  = MIN( M, N )
-C
-      INFO = 0
-      IF( .NOT.CONT .AND. .NOT.LSAME( DICO, 'D' ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.NOFACT .AND. .NOT.LSAME( FACT, 'F' ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.LTRANS .AND. .NOT.LSAME( TRANS, 'N' ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( LDQ.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( ( LDB.LT.MAX( 1, N ) )  .OR.
-     $         ( LDB.LT.MAX( 1, N, M ) .AND. .NOT.LTRANS ) ) THEN
-         INFO = -11
-      ELSE IF( LDWORK.LT.1 .OR. ( M.GT.0 .AND. LDWORK.LT.4*N + MINMN ) )
-     $      THEN
-         INFO = -16
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB03OD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MINMN.EQ.0 ) THEN
-         IF( M.EQ.0 )
-     $      CALL DLASET( 'Full', N, N, ZERO, ZERO, B, LDB )
-         SCALE = ONE
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Start the solution.
-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 ( NOFACT ) THEN
-C
-C        Find the Schur factorization of A,   A = Q*S*Q'.
-C        Workspace:  need   3*N;
-C                    prefer larger.
-C
-         CALL DGEES( 'Vectors', 'Not ordered', SELECT, N, A, LDA, SDIM,
-     $               WR, WI, Q, LDQ, DWORK, LDWORK, BWORK, INFORM )
-         IF ( INFORM.NE.0 ) THEN
-            INFO = 6
-            RETURN
-         END IF
-         WRKOPT = DWORK(1)
-C
-C        Check the eigenvalues for stability.
-C
-         IF ( CONT ) THEN
-            EMAX = WR(1)
-C
-            DO 20 J = 2, N
-               IF ( WR(J).GT.EMAX )
-     $            EMAX = WR(J)
-   20       CONTINUE
-C
-         ELSE
-            EMAX = DLAPY2( WR(1), WI(1) )
-C
-            DO 40 J = 2, N
-               TEMP = DLAPY2( WR(J), WI(J) )
-               IF ( TEMP.GT.EMAX )
-     $            EMAX = TEMP
-   40       CONTINUE
-C
-         END IF
-C
-         IF (    ( CONT ) .AND. ( EMAX.GE.ZERO ) .OR.
-     $      ( .NOT.CONT ) .AND. ( EMAX.GE.ONE  ) ) THEN
-            INFO = 2
-            RETURN
-         END IF
-      ELSE
-         WRKOPT = 0
-      END IF
-C
-C     Perform the QR or RQ factorization of B,
-C            _   _           _   _  _
-C        B = P ( R ), or B = P ( R  Z ), if TRANS = 'N', or
-C              ( 0 )
-C                                 _
-C                 _   _         ( Z ) _
-C        B = ( 0  R ) P, or B = ( _ ) P, if TRANS = 'T'.
-C                               ( R )
-C     Workspace:  need   MIN(M,N) + N;
-C                 prefer MIN(M,N) + N*NB.
-C
-      ITAU  = 1
-      JWORK = ITAU + MINMN
-      IF ( LTRANS ) THEN
-         CALL DGERQF( N, M, B, LDB, DWORK(ITAU), DWORK(JWORK),
-     $                LDWORK-JWORK+1, IFAIL )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(JWORK) ) + JWORK - 1, MINMN*N)
-         JWORK = ITAU
-C
-C        Form in B
-C        _      _              _         _   _                    _
-C        B := Q'R,   m >= n,   B := Q'*( Z'  R' )',   m < n, with B an
-C        n-by-min(m,n) matrix.
-C        Use a BLAS 3 operation if enough workspace, and BLAS 2,
-C                   _
-C        otherwise: B is formed column by column.
-C
-         IF ( LDWORK.GE.JWORK+MINMN*N-1 ) THEN
-            K = JWORK
-C
-            DO 60 I = 1, MINMN
-               CALL DCOPY( N, Q(N-MINMN+I,1), LDQ, DWORK(K), 1 )
-               K = K + N
-   60       CONTINUE
-C
-            CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Non-unit',
-     $                  N, MINMN, ONE, B(N-MINMN+1,M-MINMN+1), LDB,
-     $                  DWORK(JWORK), N )
-            IF ( M.LT.N )
-     $         CALL DGEMM( 'Transpose', 'No transpose', N, M, N-M,
-     $                     ONE, Q, LDQ, B, LDB, ONE, DWORK(JWORK), N )
-            CALL DLACPY( 'Full', N, MINMN, DWORK(JWORK), N, B, LDB )
-         ELSE
-            NE = N - MINMN
-C
-            DO 80 J = 1, MINMN
-               NE = NE + 1
-               CALL DCOPY( NE, B(1,M-MINMN+J), 1, DWORK(JWORK), 1 )
-               CALL DGEMV( 'Transpose', NE, N, ONE, Q, LDQ,
-     $                     DWORK(JWORK), 1, ZERO, B(1,J), 1 )
-   80       CONTINUE
-C
-         END IF
-      ELSE
-         CALL DGEQRF( M, N, B, LDB, DWORK(ITAU), DWORK(JWORK),
-     $                LDWORK-JWORK+1, IFAIL )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(JWORK) ) + JWORK - 1, MINMN*N)
-         JWORK = ITAU
-C
-C        Form in B
-C        _    _               _      _  _                    _
-C        B := RQ,   m >= n,   B := ( R  Z )*Q,   m < n, with B an
-C        min(m,n)-by-n matrix.
-C        Use a BLAS 3 operation if enough workspace, and BLAS 2,
-C                   _
-C        otherwise: B is formed row by row.
-C
-         IF ( LDWORK.GE.JWORK+MINMN*N-1 ) THEN
-            CALL DLACPY( 'Full', MINMN, N, Q, LDQ, DWORK(JWORK), MINMN )
-            CALL DTRMM( 'Left', 'Upper', 'No transpose', 'Non-unit',
-     $                  MINMN, N, ONE, B, LDB, DWORK(JWORK), MINMN )
-            IF ( M.LT.N )
-     $         CALL DGEMM( 'No transpose', 'No transpose', M, N, N-M,
-     $                     ONE, B(1,M+1), LDB, Q(M+1,1), LDQ, ONE,
-     $                     DWORK(JWORK), MINMN )
-            CALL DLACPY( 'Full', MINMN, N, DWORK(JWORK), MINMN, B, LDB )
-         ELSE
-            NE = MINMN + MAX( 0, N-M )
-C
-            DO 100 J = 1, MINMN
-               CALL DCOPY( NE, B(J,J), LDB, DWORK(JWORK), 1 )
-               CALL DGEMV( 'Transpose', NE, N, ONE, Q(J,1), LDQ,
-     $                     DWORK(JWORK), 1, ZERO, B(J,1), LDB )
-               NE = NE - 1
-  100       CONTINUE
-C
-         END IF
-      END IF
-      JWORK  = ITAU + MINMN
-C
-C     Solve for U the transformed Lyapunov equation
-C                                                      2    _      _
-C     op(S)'*op(U)'*op(U) + op(U)'*op(U)*op(S) = -scale *op(B)'*op(B),
-C
-C     or
-C                                                      2    _      _
-C     op(S)'*op(U)'*op(U)*op(S) - op(U)'*op(U) = -scale *op(B)'*op(B)
-C
-C     Workspace:  need   MIN(M,N) + 4*N;
-C                 prefer larger.
-C
-      CALL SB03OU( .NOT.CONT, LTRANS, N, MINMN, A, LDA, B, LDB,
-     $             DWORK(ITAU), B, LDB, SCALE, DWORK(JWORK),
-     $             LDWORK-JWORK+1, INFO )
-      IF ( INFO.GT.1 ) THEN
-         INFO = INFO + 1
-         RETURN
-      END IF
-      WRKOPT = MAX( WRKOPT, INT( DWORK(JWORK) ) + JWORK - 1 )
-      JWORK  = ITAU
-C
-C     Form   U :=  U*Q' or U := Q*U in the array B.
-C     Use a BLAS 3 operation if enough workspace, and BLAS 2, otherwise.
-C     Workspace:  need   N;
-C                 prefer N*N;
-C
-      IF ( LDWORK.GE.JWORK+N*N-1 ) THEN
-         IF ( LTRANS ) THEN
-            CALL DLACPY( 'Full', N, N, Q, LDQ, DWORK(JWORK), N )
-            CALL DTRMM( 'Right', 'Upper', 'No transpose', 'Non-unit', N,
-     $                  N, ONE, B, LDB, DWORK(JWORK), N )
-         ELSE
-            K = JWORK
-C
-            DO 120 I = 1, N
-               CALL DCOPY( N, Q(1,I), 1, DWORK(K), N )
-               K = K + 1
-  120       CONTINUE
-C
-            CALL DTRMM( 'Left', 'Upper', 'No transpose', 'Non-unit', N,
-     $                  N, ONE, B, LDB, DWORK(JWORK), N )
-         END IF
-         CALL DLACPY( 'Full', N, N, DWORK(JWORK), N, B, LDB )
-         WRKOPT = MAX( WRKOPT, JWORK + N*N - 1 )
-      ELSE
-         IF ( LTRANS ) THEN
-C
-C           U is formed column by column ( U := Q*U ).
-C
-            DO 140 I = 1, N
-               CALL DCOPY( I, B(1,I), 1, DWORK(JWORK), 1 )
-               CALL DGEMV( 'No transpose', N, I, ONE, Q, LDQ,
-     $                     DWORK(JWORK), 1, ZERO, B(1,I), 1 )
-  140       CONTINUE
-         ELSE
-C
-C           U is formed row by row ( U' := Q*U' ).
-C
-            DO 160 I = 1, N
-               CALL DCOPY( N-I+1, B(I,I), LDB, DWORK(JWORK), 1 )
-               CALL DGEMV( 'No transpose', N, N-I+1, ONE, Q(1,I), LDQ,
-     $                     DWORK(JWORK), 1, ZERO, B(I,1), LDB )
-  160       CONTINUE
-         END IF
-      END IF
-C
-C     Lastly find the QR or RQ factorization of U, overwriting on B,
-C     to give the required Cholesky factor.
-C     Workspace:  need   2*N;
-C                 prefer N + N*NB;
-C
-      JWORK = ITAU + N
-      IF ( LTRANS ) THEN
-         CALL DGERQF( N, N, B, LDB, DWORK(ITAU), DWORK(JWORK),
-     $                LDWORK-JWORK+1, IFAIL )
-      ELSE
-         CALL DGEQRF( N, N, B, LDB, DWORK(ITAU), DWORK(JWORK),
-     $                LDWORK-JWORK+1, IFAIL )
-      END IF
-      WRKOPT = MAX( WRKOPT, INT( DWORK(JWORK) ) + JWORK - 1 )
-C
-C     Make the diagonal elements of U non-negative.
-C
-      IF ( LTRANS ) THEN
-C
-         DO 200 J = 1, N
-            IF ( B(J,J).LT.ZERO ) THEN
-C
-               DO 180 I = 1, J
-                  B(I,J) = -B(I,J)
-  180          CONTINUE
-C
-            END IF
-  200    CONTINUE
-C
-      ELSE
-         K = JWORK
-C
-         DO 240 J = 1, N
-            DWORK(K) = B(J,J)
-            L = JWORK
-C
-            DO 220 I = 1, J
-               IF ( DWORK(L).LT.ZERO ) B(I,J) = -B(I,J)
-               L = L + 1
-  220       CONTINUE
-C
-            K = K + 1
-  240    CONTINUE
-      END IF
-C
-      IF( N.GT.1 )
-     $   CALL DLASET( 'Lower', N-1, N-1, ZERO, ZERO, B(2,1), LDB )
-C
-C     Set the optimal workspace.
-C
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of SB03OD ***
-      END
--- a/extra/control-devel/src/SB03OR.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,429 +0,0 @@
-      SUBROUTINE SB03OR( DISCR, LTRANS, N, M, S, LDS, A, LDA, C, LDC,
-     $                   SCALE, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute the solution of the Sylvester equations
-C
-C        op(S)'*X + X*op(A) = scale*C, if DISCR = .FALSE.  or
-C
-C        op(S)'*X*op(A) - X = scale*C, if DISCR = .TRUE.
-C
-C     where op(K) = K or K' (i.e., the transpose of the matrix K), S is
-C     an N-by-N block upper triangular matrix with one-by-one and
-C     two-by-two blocks on the diagonal, A is an M-by-M matrix (M = 1 or
-C     M = 2), X and C are each N-by-M matrices, and scale is an output
-C     scale factor, set less than or equal to 1 to avoid overflow in X.
-C     The solution X is overwritten on C.
-C
-C     SB03OR  is a service routine for the Lyapunov solver  SB03OT.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DISCR   LOGICAL
-C             Specifies the equation to be solved:
-C             = .FALSE.:  op(S)'*X + X*op(A) = scale*C;
-C             = .TRUE. :  op(S)'*X*op(A) - X = scale*C.
-C
-C     LTRANS  LOGICAL
-C             Specifies the form of op(K) to be used, as follows:
-C             = .FALSE.:  op(K) = K    (No transpose);
-C             = .TRUE. :  op(K) = K**T (Transpose).
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix  S  and also the number of rows of
-C             matrices  X and C.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The order of the matrix  A  and also the number of columns
-C             of matrices  X and C.  M = 1 or M = 2.
-C
-C     S       (input) DOUBLE PRECISION array, dimension (LDS,N)
-C             The leading  N-by-N  upper Hessenberg part of the array  S
-C             must contain the block upper triangular matrix. The
-C             elements below the upper Hessenberg part of the array  S
-C             are not referenced.  The array  S  must not contain
-C             diagonal blocks larger than two-by-two and the two-by-two
-C             blocks must only correspond to complex conjugate pairs of
-C             eigenvalues, not to real eigenvalues.
-C
-C     LDS     INTEGER
-C             The leading dimension of array S.  LDS >= MAX(1,N).
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDS,M)
-C             The leading  M-by-M  part of this array must contain a
-C             given matrix, where M = 1 or M = 2.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= M.
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,M)
-C             On entry, C must contain an N-by-M matrix, where M = 1 or
-C             M = 2.
-C             On exit, C contains the N-by-M matrix X, the solution of
-C             the Sylvester equation.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,N).
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor, scale, set less than or equal to 1 to
-C             prevent the solution overflowing.
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             = 0:  successful exit;
-C             = 1:  if DISCR = .FALSE., and S and -A have common
-C                   eigenvalues, or if DISCR = .TRUE., and S and A have
-C                   eigenvalues whose product is equal to unity;
-C                   a solution has been computed using slightly
-C                   perturbed values.
-C
-C     METHOD
-C
-C     The LAPACK scheme for solving Sylvester equations is adapted.
-C
-C     REFERENCES
-C
-C     [1] Hammarling, S.J.
-C         Numerical solution of the stable, non-negative definite
-C         Lyapunov equation.
-C         IMA J. Num. Anal., 2, pp. 303-325, 1982.
-C
-C     NUMERICAL ASPECTS
-C                               2
-C     The algorithm requires 0(N M) operations and is backward stable.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, May 1997.
-C     Supersedes Release 2.0 routines SB03CW and SB03CX by
-C     Sven Hammarling, NAG Ltd, United Kingdom, Oct. 1986.
-C     Partly based on routine PLYAP4 by A. Varga, University of Bochum,
-C     May 1992.
-C
-C     REVISIONS
-C
-C     December 1997, April 1998, May 1999, April 2000.
-C
-C     KEYWORDS
-C
-C     Lyapunov equation, orthogonal transformation, real Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
-C     .. Scalar Arguments ..
-      LOGICAL            DISCR, LTRANS
-      INTEGER            INFO, LDA, LDS, LDC, M, N
-      DOUBLE PRECISION   SCALE
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A( LDA, * ), C( LDC, * ), S( LDS, * )
-C     .. Local Scalars ..
-      LOGICAL            TBYT
-      INTEGER            DL, INFOM, ISGN, J, L, L1, L2, L2P1, LNEXT
-      DOUBLE PRECISION   G11, G12, G21, G22, SCALOC, XNORM
-C     ..
-C     .. Local Arrays ..
-      DOUBLE PRECISION   AT( 2, 2 ), VEC( 2, 2 ), X( 2, 2 )
-C     ..
-C     .. External Functions ..
-      DOUBLE PRECISION   DDOT
-      EXTERNAL           DDOT
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DLASY2, DSCAL, SB04PX, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-      INFO = 0
-C
-C     Test the input scalar arguments.
-C
-      IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( .NOT.( M.EQ.1 .OR. M.EQ.2 ) ) THEN
-         INFO = -4
-      ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDA.LT.M ) THEN
-         INFO = -8
-      ELSE IF( LDC.LT.MAX( 1, N ) ) THEN
-         INFO = -10
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB03OR', -INFO )
-         RETURN
-      END IF
-C
-      SCALE = ONE
-C
-C     Quick return if possible.
-C
-      IF ( N.EQ.0 )
-     $   RETURN
-C
-      ISGN = 1
-      TBYT = M.EQ.2
-      INFOM = 0
-C
-C     Construct A'.
-C
-      AT(1,1) = A(1,1)
-      IF ( TBYT ) THEN
-         AT(1,2) = A(2,1)
-         AT(2,1) = A(1,2)
-         AT(2,2) = A(2,2)
-      END IF
-C
-      IF ( LTRANS ) THEN
-C
-C        Start row loop (index = L).
-C        L1 (L2) : row index of the first (last) row of X(L).
-C
-         LNEXT = N
-C
-         DO 20 L = N, 1, -1
-            IF( L.GT.LNEXT )
-     $         GO TO 20
-            L1 = L
-            L2 = L
-            IF( L.GT.1 ) THEN
-               IF( S( L, L-1 ).NE.ZERO )
-     $            L1 = L1 - 1
-               LNEXT = L1 - 1
-            END IF
-            DL = L2 - L1 + 1
-            L2P1 = MIN( L2+1, N )
-C
-            IF ( DISCR ) THEN
-C
-C              Solve  S*X*A' - X = scale*C.
-C
-C              The L-th block of X is determined from
-C
-C              S(L,L)*X(L)*A' - X(L) = C(L) - R(L),
-C
-C              where
-C
-C                      N
-C              R(L) = SUM [S(L,J)*X(J)] * A' .
-C                    J=L+1
-C
-               G11 = -DDOT( N-L2, S( L1, L2P1 ), LDS, C( L2P1, 1 ), 1 )
-               IF ( TBYT ) THEN
-                  G12 = -DDOT( N-L2, S( L1, L2P1 ), LDS, C( L2P1, 2 ),
-     $                         1 )
-                  VEC( 1, 1 ) = C( L1, 1 ) + G11*AT(1,1) + G12*AT(2,1)
-                  VEC( 1, 2 ) = C( L1, 2 ) + G11*AT(1,2) + G12*AT(2,2)
-               ELSE
-                  VEC (1, 1 ) = C( L1, 1 ) + G11*AT(1,1)
-               END IF
-               IF ( DL.NE.1 ) THEN
-                  G21 = -DDOT( N-L2, S( L2, L2P1 ), LDS, C( L2P1, 1 ),
-     $                         1 )
-                  IF ( TBYT ) THEN
-                     G22 = -DDOT( N-L2, S( L2, L2P1 ), LDS,
-     $                            C( L2P1, 2 ), 1 )
-                     VEC( 2, 1 ) = C( L2, 1 ) + G21*AT(1,1) +
-     $                                          G22*AT(2,1)
-                     VEC( 2, 2 ) = C( L2, 2 ) + G21*AT(1,2) +
-     $                                          G22*AT(2,2)
-                  ELSE
-                     VEC( 2, 1 ) = C( L2, 1 ) + G21*AT(1,1)
-                  END IF
-               END IF
-               CALL SB04PX( .FALSE., .FALSE., -ISGN, DL, M, S( L1, L1 ),
-     $                      LDS, AT, 2, VEC, 2, SCALOC, X, 2, XNORM,
-     $                      INFO )
-            ELSE
-C
-C              Solve  S*X + X*A' = scale*C.
-C
-C              The L-th block of X is determined from
-C
-C              S(L,L)*X(L) + X(L)*A' = C(L) - R(L),
-C
-C              where
-C                       N
-C              R(L) =  SUM S(L,J)*X(J) .
-C                     J=L+1
-C
-               VEC( 1, 1 ) = C( L1, 1 ) -
-     $                       DDOT( N-L2, S( L1, L2P1 ), LDS,
-     $                             C( L2P1, 1 ), 1 )
-               IF ( TBYT )
-     $            VEC( 1, 2 ) = C( L1, 2 ) -
-     $                          DDOT( N-L2, S( L1, L2P1 ), LDS,
-     $                                C( L2P1, 2 ), 1 )
-C
-               IF ( DL.NE.1 ) THEN
-                  VEC( 2, 1 ) = C( L2, 1 ) -
-     $                          DDOT( N-L2, S( L2, L2P1 ), LDS,
-     $                                C( L2P1, 1 ), 1 )
-                  IF ( TBYT )
-     $               VEC( 2, 2 ) = C( L2, 2 ) -
-     $                             DDOT( N-L2, S( L2, L2P1 ), LDS,
-     $                                   C( L2P1, 2 ), 1 )
-               END IF
-               CALL DLASY2( .FALSE., .FALSE., ISGN, DL, M, S( L1, L1 ),
-     $                      LDS, AT, 2, VEC, 2, SCALOC, X, 2, XNORM,
-     $                      INFO )
-            END IF
-            INFOM = MAX( INFO, INFOM )
-            IF ( SCALOC.NE.ONE ) THEN
-C
-               DO 10 J = 1, M
-                  CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   10          CONTINUE
-C
-               SCALE = SCALE*SCALOC
-            END IF
-            C( L1, 1 ) = X( 1, 1 )
-            IF ( TBYT ) C( L1, 2 ) = X( 1, 2 )
-            IF ( DL.NE.1 ) THEN
-               C( L2, 1 ) = X( 2, 1 )
-               IF ( TBYT ) C( L2, 2 ) = X( 2, 2 )
-            END IF
-   20    CONTINUE
-C
-      ELSE
-C
-C        Start row loop (index = L).
-C        L1 (L2) : row index of the first (last) row of X(L).
-C
-         LNEXT = 1
-C
-         DO 40 L = 1, N
-            IF( L.LT.LNEXT )
-     $         GO TO 40
-            L1 = L
-            L2 = L
-            IF( L.LT.N ) THEN
-               IF( S( L+1, L ).NE.ZERO )
-     $            L2 = L2 + 1
-               LNEXT = L2 + 1
-            END IF
-            DL = L2 - L1 + 1
-C
-            IF ( DISCR ) THEN
-C
-C              Solve  A'*X'*S - X' = scale*C'.
-C
-C              The L-th block of X is determined from
-C
-C              A'*X(L)'*S(L,L) - X(L)' = C(L)' - R(L),
-C
-C              where
-C
-C                          L-1
-C              R(L) = A' * SUM [X(J)'*S(J,L)] .
-C                          J=1
-C
-               G11 = -DDOT( L1-1, C, 1, S( 1, L1 ), 1 )
-               IF ( TBYT ) THEN
-                  G21 = -DDOT( L1-1, C( 1, 2 ), 1, S( 1, L1 ), 1 )
-                  VEC( 1, 1 ) = C( L1, 1 ) + AT(1,1)*G11 + AT(1,2)*G21
-                  VEC( 2, 1 ) = C( L1, 2 ) + AT(2,1)*G11 + AT(2,2)*G21
-               ELSE
-                  VEC (1, 1 ) = C( L1, 1 ) + AT(1,1)*G11
-               END IF
-               IF ( DL .NE. 1 ) THEN
-                  G12 = -DDOT( L1-1, C, 1, S( 1, L2 ), 1 )
-                  IF ( TBYT ) THEN
-                     G22 = -DDOT( L1-1, C( 1, 2 ), 1, S( 1, L2 ), 1 )
-                     VEC( 1, 2 ) = C( L2, 1 ) + AT(1,1)*G12 +
-     $                                          AT(1,2)*G22
-                     VEC( 2, 2 ) = C( L2, 2 ) + AT(2,1)*G12 +
-     $                                          AT(2,2)*G22
-                  ELSE
-                     VEC( 1, 2 ) = C( L2, 1 ) + AT(1,1)*G12
-                  END IF
-               END IF
-               CALL SB04PX( .FALSE., .FALSE., -ISGN, M, DL, AT, 2,
-     $                      S( L1, L1 ), LDS, VEC, 2, SCALOC, X, 2,
-     $                      XNORM, INFO )
-            ELSE
-C
-C              Solve  A'*X' + X'*S = scale*C'.
-C
-C              The L-th block of X is determined from
-C
-C              A'*X(L)' + X(L)'*S(L,L) = C(L)' - R(L),
-C
-C              where
-C                     L-1
-C              R(L) = SUM [X(J)'*S(J,L)].
-C                     J=1
-C
-               VEC( 1, 1 ) = C( L1, 1 ) -
-     $                       DDOT( L1-1, C, 1, S( 1, L1 ), 1 )
-               IF ( TBYT )
-     $            VEC( 2, 1 ) = C( L1, 2 ) -
-     $                          DDOT( L1-1, C( 1, 2 ), 1, S( 1, L1 ), 1)
-C
-               IF ( DL.NE.1 ) THEN
-                  VEC( 1, 2 ) = C( L2, 1 ) -
-     $                          DDOT( L1-1, C, 1, S( 1, L2 ), 1 )
-                  IF ( TBYT )
-     $            VEC( 2, 2 ) = C( L2, 2 ) -
-     $                          DDOT( L1-1, C( 1, 2 ), 1, S( 1, L2 ), 1)
-               END IF
-               CALL DLASY2( .FALSE., .FALSE., ISGN, M, DL, AT, 2,
-     $                      S( L1, L1 ), LDS, VEC, 2, SCALOC, X, 2,
-     $                      XNORM, INFO )
-            END IF
-            INFOM = MAX( INFO, INFOM )
-            IF ( SCALOC.NE.ONE ) THEN
-C
-               DO 30 J = 1, M
-                  CALL DSCAL( N, SCALOC, C( 1, J ), 1 )
-   30          CONTINUE
-C
-               SCALE = SCALE*SCALOC
-            END IF
-            C( L1, 1 ) = X( 1, 1 )
-            IF ( TBYT ) C( L1, 2 ) = X( 2, 1 )
-            IF ( DL.NE.1 ) THEN
-               C( L2, 1 ) = X( 1, 2 )
-               IF ( TBYT ) C( L2, 2 ) = X( 2, 2 )
-            END IF
-   40    CONTINUE
-      END IF
-C
-      INFO = INFOM
-      RETURN
-C *** Last line of SB03OR ***
-      END
--- a/extra/control-devel/src/SB03OT.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,984 +0,0 @@
-      SUBROUTINE SB03OT( DISCR, LTRANS, N, S, LDS, R, LDR, SCALE, DWORK,
-     $                   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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To solve for X = op(U)'*op(U) either the stable non-negative
-C     definite continuous-time Lyapunov equation
-C                                   2
-C        op(S)'*X + X*op(S) = -scale *op(R)'*op(R)                   (1)
-C
-C     or the convergent non-negative definite discrete-time Lyapunov
-C     equation
-C                                   2
-C        op(S)'*X*op(S) - X = -scale *op(R)'*op(R)                   (2)
-C
-C     where op(K) = K or K' (i.e., the transpose of the matrix K), S is
-C     an N-by-N block upper triangular matrix with one-by-one or
-C     two-by-two blocks on the diagonal, R is an N-by-N upper triangular
-C     matrix, and scale is an output scale factor, set less than or
-C     equal to 1 to avoid overflow in X.
-C
-C     In the case of equation (1) the matrix S must be stable (that
-C     is, all the eigenvalues of S must have negative real parts),
-C     and for equation (2) the matrix S must be convergent (that is,
-C     all the eigenvalues of S must lie inside the unit circle).
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DISCR   LOGICAL
-C             Specifies the type of Lyapunov equation to be solved as
-C             follows:
-C             = .TRUE. :  Equation (2), discrete-time case;
-C             = .FALSE.:  Equation (1), continuous-time case.
-C
-C     LTRANS  LOGICAL
-C             Specifies the form of op(K) to be used, as follows:
-C             = .FALSE.:  op(K) = K    (No transpose);
-C             = .TRUE. :  op(K) = K**T (Transpose).
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices S and R.  N >= 0.
-C
-C     S       (input) DOUBLE PRECISION array of dimension (LDS,N)
-C             The leading N-by-N upper Hessenberg part of this array
-C             must contain the block upper triangular matrix.
-C             The elements below the upper Hessenberg part of the array
-C             S are not referenced. The 2-by-2 blocks must only
-C             correspond to complex conjugate pairs of eigenvalues (not
-C             to real eigenvalues).
-C
-C     LDS     INTEGER
-C             The leading dimension of array S.  LDS >= MAX(1,N).
-C
-C     R       (input/output) DOUBLE PRECISION array of dimension (LDR,N)
-C             On entry, the leading N-by-N upper triangular part of this
-C             array must contain the upper triangular matrix R.
-C             On exit, the leading N-by-N upper triangular part of this
-C             array contains the upper triangular matrix U.
-C             The strict lower triangle of R is not referenced.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,N).
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor, scale, set less than or equal to 1 to
-C             prevent the solution overflowing.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (4*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 Lyapunov equation is (nearly) singular
-C                   (warning indicator);
-C                   if DISCR = .FALSE., this means that while the
-C                   matrix S has computed eigenvalues with negative real
-C                   parts, it is only just stable in the sense that
-C                   small perturbations in S can make one or more of the
-C                   eigenvalues have a non-negative real part;
-C                   if DISCR = .TRUE., this means that while the
-C                   matrix S has computed eigenvalues inside the unit
-C                   circle, it is nevertheless only just convergent, in
-C                   the sense that small perturbations in S can make one
-C                   or more of the eigenvalues lie outside the unit
-C                   circle;
-C                   perturbed values were used to solve the equation
-C                   (but the matrix S is unchanged);
-C             = 2:  if the matrix S is not stable (that is, one or more
-C                   of the eigenvalues of S has a non-negative real
-C                   part), if DISCR = .FALSE., or not convergent (that
-C                   is, one or more of the eigenvalues of S lies outside
-C                   the unit circle), if DISCR = .TRUE.;
-C             = 3:  if the matrix S has two or more consecutive non-zero
-C                   elements on the first sub-diagonal, so that there is
-C                   a block larger than 2-by-2 on the diagonal;
-C             = 4:  if the matrix S has a 2-by-2 diagonal block with
-C                   real eigenvalues instead of a complex conjugate
-C                   pair.
-C
-C     METHOD
-C
-C     The method used by the routine is based on a variant of the
-C     Bartels and Stewart backward substitution method [1], that finds
-C     the Cholesky factor op(U) directly without first finding X and
-C     without the need to form the normal matrix op(R)'*op(R) [2].
-C
-C     The continuous-time Lyapunov equation in the canonical form
-C                                                        2
-C       op(S)'*op(U)'*op(U) + op(U)'*op(U)*op(S) = -scale *op(R)'*op(R),
-C
-C     or the discrete-time Lyapunov equation in the canonical form
-C                                                        2
-C       op(S)'*op(U)'*op(U)*op(S) - op(U)'*op(U) = -scale *op(R)'*op(R),
-C
-C     where U and R are upper triangular, is solved for U.
-C
-C     REFERENCES
-C
-C     [1] Bartels, R.H. and Stewart, G.W.
-C         Solution of the matrix equation  A'X + XB = C.
-C         Comm. A.C.M., 15, pp. 820-826, 1972.
-C
-C     [2] Hammarling, S.J.
-C         Numerical solution of the stable, non-negative definite
-C         Lyapunov equation.
-C         IMA J. Num. Anal., 2, pp. 303-325, 1982.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations and is backward stable.
-C
-C     FURTHER COMMENTS
-C
-C     The Lyapunov equation may be very ill-conditioned. In particular
-C     if S is only just stable (or convergent) then the Lyapunov
-C     equation will be ill-conditioned. "Large" elements in U relative
-C     to those of S and R, or a "small" value for scale, is a symptom
-C     of ill-conditioning. A condition estimate can be computed using
-C     SLICOT Library routine SB03MD.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, May 1997.
-C     Supersedes Release 2.0 routine SB03CZ by Sven Hammarling,
-C     NAG Ltd, United Kingdom, Oct. 1986.
-C     Partly based on SB03CZ and PLYAP1 by A. Varga, University of
-C     Bochum, May 1992.
-C
-C     REVISIONS
-C
-C     Dec. 1997, April 1998, May 1999, Feb. 2004.
-C
-C     KEYWORDS
-C
-C     Lyapunov equation, orthogonal transformation, real Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE, TWO
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0 )
-C     .. Scalar Arguments ..
-      LOGICAL           DISCR, LTRANS
-      INTEGER           INFO, LDR, LDS, N
-      DOUBLE PRECISION  SCALE
-C     .. Array Arguments ..
-      DOUBLE PRECISION  DWORK(*), R(LDR,*), S(LDS,*)
-C     .. Local Scalars ..
-      LOGICAL           CONT, TBYT
-      INTEGER           INFOM, ISGN, J, J1, J2, J3, K, K1, K2, K3,
-     $                  KOUNT, KSIZE
-      DOUBLE PRECISION  ABSSKK, ALPHA, BIGNUM, D1, D2, DR, EPS, SCALOC,
-     $                  SMIN, SMLNUM, SUM, T1, T2, T3, T4, TAU1, TAU2,
-     $                  TEMP, V1, V2, V3, V4
-C     .. Local Arrays ..
-      DOUBLE PRECISION  A(2,2), B(2,2), U(2,2)
-C     .. External Functions ..
-      DOUBLE PRECISION  DLAMCH, DLANHS
-      EXTERNAL          DLAMCH, DLANHS
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DCOPY, DLABAD, DLARFG, DSCAL, DSWAP,
-     $                  DTRMM, DTRMV, MB04ND, MB04OD, SB03OR, SB03OY,
-     $                  XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         ABS, MAX, SIGN, SQRT
-C     .. Executable Statements ..
-C
-      INFO = 0
-C
-C     Test the input scalar arguments.
-C
-      IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
-         INFO = -5
-      ELSE IF( LDR.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB03OT', -INFO )
-         RETURN
-      END IF
-C
-      SCALE = ONE
-C
-C     Quick return if possible.
-C
-      IF (N.EQ.0)
-     $   RETURN
-C
-C     Set constants to control overflow.
-C
-      EPS = DLAMCH( 'P' )
-      SMLNUM = DLAMCH( 'S' )
-      BIGNUM = ONE / SMLNUM
-      CALL DLABAD( SMLNUM, BIGNUM )
-      SMLNUM = SMLNUM*DBLE( N*N ) / EPS
-      BIGNUM = ONE / SMLNUM
-C
-      SMIN = MAX( SMLNUM, EPS*DLANHS( 'Max', N, S, LDS, DWORK ) )
-      INFOM = 0
-C
-C     Start the solution. Most of the comments refer to notation and
-C     equations in sections 5 and 10 of the second reference above.
-C
-C     Determine whether or not the current block is two-by-two.
-C     K gives the position of the start of the current block and
-C     TBYT is true if the block is two-by-two.
-C
-      CONT = .NOT.DISCR
-      ISGN = 1
-      IF ( .NOT.LTRANS ) THEN
-C
-C        Case op(M) = M.
-C
-         KOUNT = 1
-C
-   10    CONTINUE
-C        WHILE( KOUNT.LE.N )LOOP
-         IF ( KOUNT.LE.N ) THEN
-            K = KOUNT
-            IF ( KOUNT.GE.N ) THEN
-               TBYT  = .FALSE.
-               KOUNT = KOUNT + 1
-            ELSE IF ( S(K+1,K).EQ.ZERO ) THEN
-               TBYT  = .FALSE.
-               KOUNT = KOUNT + 1
-            ELSE
-               TBYT = .TRUE.
-               IF ( (K+1).LT.N ) THEN
-                  IF ( S(K+2,K+1).NE.ZERO ) THEN
-                     INFO = 3
-                     RETURN
-                  END IF
-               END IF
-               KOUNT = KOUNT + 2
-            END IF
-            IF ( TBYT ) THEN
-C
-C              Solve the two-by-two Lyapunov equation (6.1) or (10.19),
-C              using the routine SB03OY.
-C
-               B(1,1) = S(K,K)
-               B(2,1) = S(K+1,K)
-               B(1,2) = S(K,K+1)
-               B(2,2) = S(K+1,K+1)
-               U(1,1) = R(K,K)
-               U(1,2) = R(K,K+1)
-               U(2,2) = R(K+1,K+1)
-C
-               CALL SB03OY( DISCR, LTRANS, ISGN, B, 2, U, 2, A, 2,
-     $                      SCALOC, INFO )
-               IF ( INFO.GT.1 )
-     $            RETURN
-               INFOM = MAX( INFO, INFOM )
-               IF( SCALOC.NE.ONE ) THEN
-C
-                  DO 20 J = 1, N
-                     CALL DSCAL( J, SCALOC, R(1,J), 1 )
-   20             CONTINUE
-C
-                  SCALE = SCALE*SCALOC
-               END IF
-               R(K,K)     = U(1,1)
-               R(K,K+1)   = U(1,2)
-               R(K+1,K+1) = U(2,2)
-C
-C              If we are not at the end of S then set up and solve
-C              equation (6.2) or (10.20).
-C
-C              Note that  SB03OY  returns  ( u11*s11*inv( u11 ) ) in  B
-C              and returns scaled alpha in  A.  ksize is the order of
-C              the remainder of  S.  k1, k2 and k3  point to the start
-C              of vectors in  DWORK.
-C
-               IF ( KOUNT.LE.N ) THEN
-                  KSIZE = N - K - 1
-                  K1 = KSIZE + 1
-                  K2 = KSIZE + K1
-                  K3 = KSIZE + K2
-C
-C                 Form the right-hand side of (6.2) or (10.20), the
-C                 first column in DWORK( 1 ) ,..., DWORK( n - k - 1 )
-C                 the second in DWORK( n - k ) ,...,
-C                 DWORK( 2*( n - k - 1 ) ).
-C
-                  CALL DCOPY( KSIZE, R(K,K+2), LDR, DWORK, 1 )
-                  CALL DCOPY( KSIZE, R(K+1,K+2), LDR, DWORK(K1), 1 )
-                  CALL DTRMM( 'Right', 'Upper', 'No transpose',
-     $                        'Non-unit', KSIZE, 2, -ONE, A, 2, DWORK,
-     $                        KSIZE )
-                  IF ( CONT ) THEN
-                     CALL DAXPY( KSIZE, -R(K,K), S(K,K+2), LDS, DWORK,
-     $                           1 )
-                     CALL DAXPY( KSIZE, -R(K,K+1), S(K+1,K+2), LDS,
-     $                           DWORK, 1)
-                     CALL DAXPY( KSIZE, -R(K+1,K+1), S(K+1,K+2), LDS,
-     $                           DWORK(K1), 1 )
-                  ELSE
-                     CALL DAXPY( KSIZE, -R(K,K)*B(1,1), S(K,K+2), LDS,
-     $                           DWORK, 1 )
-                     CALL DAXPY( KSIZE, -( R(K,K+1)*B(1,1) + R(K+1,K+1)
-     $                           *B(2,1) ), S(K+1,K+2), LDS, DWORK, 1 )
-                     CALL DAXPY( KSIZE, -R(K,K)*B(1,2), S(K,K+2), LDS,
-     $                           DWORK(K1), 1 )
-                     CALL DAXPY( KSIZE, -( R(K,K+1)*B(1,2) + R(K+1,K+1)
-     $                           *B(2,2) ), S(K+1,K+2), LDS, DWORK(K1),
-     $                           1 )
-                  END IF
-C
-C                 SB03OR  solves the Sylvester equations. The solution
-C                 is overwritten on DWORK.
-C
-                  CALL SB03OR( DISCR, LTRANS, KSIZE, 2, S(K+2,K+2), LDS,
-     $                         B, 2, DWORK, KSIZE, SCALOC, INFO )
-                  INFOM = MAX( INFO, INFOM )
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 30 J = 1, N
-                        CALL DSCAL( J, SCALOC, R(1,J), 1 )
-   30                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-C
-C                 Copy the solution into the next  2*( n - k - 1 )
-C                 elements of  DWORK.
-C
-                  CALL DCOPY( 2*KSIZE, DWORK, 1, DWORK(K2), 1 )
-C
-C                 Now form the matrix  Rhat  of equation (6.4) or
-C                 (10.22). Note that (10.22) is incorrect, so here we
-C                 implement a corrected version of (10.22).
-C
-                  IF ( CONT ) THEN
-C
-C                    Swap the two rows of R with DWORK.
-C
-                     CALL DSWAP( KSIZE, DWORK, 1, R(K,K+2), LDR )
-                     CALL DSWAP( KSIZE, DWORK(K1), 1, R(K+1,K+2), LDR )
-C
-C                    1st column:
-C
-                     CALL DAXPY( KSIZE, -A(1,1), DWORK(K2), 1, DWORK,
-     $                           1 )
-                     CALL DAXPY( KSIZE, -A(1,2), DWORK(K3), 1, DWORK,
-     $                           1 )
-C
-C                    2nd column:
-C
-                     CALL DAXPY( KSIZE, -A(2,2), DWORK(K3), 1,
-     $                           DWORK(K1), 1 )
-                  ELSE
-C
-C                    Form  v = S1'*u + s*u11', overwriting  v  on DWORK.
-C
-C                    Compute  S1'*u,  first multiplying by the
-C                    triangular part of  S1.
-C
-                     CALL DTRMM( 'Left', 'Upper', 'Transpose',
-     $                           'Non-unit', KSIZE, 2, ONE, S(K+2,K+2),
-     $                           LDS, DWORK, KSIZE )
-C
-C                    Then multiply by the subdiagonal of  S1  and add in
-C                    to the above result.
-C
-                     J1 = K1
-                     J2 = K + 2
-C
-                     DO 40 J = 1, KSIZE-1
-                        IF ( S(J2+1,J2).NE.ZERO ) THEN
-                           DWORK(J)  = S(J2+1,J2)*DWORK(K2+J) + DWORK(J)
-                           DWORK(J1) = S(J2+1,J2)*DWORK(K3+J) +
-     $                                 DWORK(J1)
-                        END IF
-                        J1 = J1 + 1
-                        J2 = J2 + 1
-   40                CONTINUE
-C
-C                    Add in s*u11'.
-C
-                     CALL DAXPY( KSIZE, R(K,K), S(K,K+2), LDS, DWORK,
-     $                           1 )
-                     CALL DAXPY( KSIZE, R(K,K+1), S(K+1,K+2), LDS,
-     $                           DWORK, 1 )
-                     CALL DAXPY( KSIZE, R(K+1,K+1), S(K+1,K+2), LDS,
-     $                           DWORK(K1), 1 )
-C
-C                    Next recover r from R, swapping r with u.
-C
-                     CALL DSWAP( KSIZE, DWORK(K2), 1, R(K,K+2), LDR )
-                     CALL DSWAP( KSIZE, DWORK(K3), 1, R(K+1,K+2), LDR )
-C
-C                    Now we perform the QR factorization.
-C
-C                    ( a ) = Q*( t ),
-C                    ( b )
-C
-C                    and form
-C
-C                    ( p' ) = Q'*( r' ).
-C                    ( y' )      ( v' )
-C
-C                    y  is then the correct vector to use in (10.22).
-C                    Note that  a  is upper triangular and that  t  and
-C                    p  are not required.
-C
-                     CALL DLARFG( 3, A(1,1), B(1,1), 1, TAU1 )
-                     V1  = B(1,1)
-                     T1  = TAU1*V1
-                     V2  = B(2,1)
-                     T2  = TAU1*V2
-                     SUM = A(1,2) + V1*B(1,2) + V2*B(2,2)
-                     B(1,2) = B(1,2) - SUM*T1
-                     B(2,2) = B(2,2) - SUM*T2
-                     CALL DLARFG( 3, A(2,2), B(1,2), 1, TAU2 )
-                     V3 = B(1,2)
-                     T3 = TAU2*V3
-                     V4 = B(2,2)
-                     T4 = TAU2*V4
-                     J1 = K1
-                     J2 = K2
-                     J3 = K3
-C
-                     DO 50 J = 1, KSIZE
-                        SUM = DWORK(J2) + V1*DWORK(J) + V2*DWORK(J1)
-                        D1  = DWORK(J)  - SUM*T1
-                        D2  = DWORK(J1) - SUM*T2
-                        SUM = DWORK(J3) + V3*D1 + V4*D2
-                        DWORK(J)  =  D1 - SUM*T3
-                        DWORK(J1) =  D2 - SUM*T4
-                        J1 = J1 + 1
-                        J2 = J2 + 1
-                        J3 = J3 + 1
-   50                CONTINUE
-C
-                  END IF
-C
-C                 Now update  R1  to give  Rhat.
-C
-                  CALL DCOPY( KSIZE, DWORK, 1, DWORK(K2), 1 )
-                  CALL DCOPY( KSIZE, DWORK(K1), 1, DWORK(K3), 1 )
-                  CALL DCOPY( KSIZE, DWORK(K3), 1, DWORK(2), 2 )
-                  CALL DCOPY( KSIZE, DWORK(K2), 1, DWORK(1), 2 )
-                  CALL MB04OD( 'Full', KSIZE, 0, 2, R(K+2,K+2), LDR,
-     $                         DWORK, 2, DWORK, 1, DWORK, 1, DWORK(K2),
-     $                         DWORK(K3) )
-               END IF
-            ELSE
-C
-C              1-by-1 block.
-C
-C              Make sure S is stable or convergent and find u11 in
-C              equation (5.13) or (10.15).
-C
-               IF ( DISCR ) THEN
-                  ABSSKK = ABS( S(K,K) )
-                  IF ( ( ABSSKK - ONE ).GE.ZERO ) THEN
-                     INFO = 2
-                     RETURN
-                  END IF
-                  TEMP = SQRT( ( ONE - ABSSKK )*( ONE + ABSSKK ) )
-               ELSE
-                  IF ( S(K,K).GE.ZERO ) THEN
-                     INFO = 2
-                     RETURN
-                  END IF
-                  TEMP = SQRT( ABS( TWO*S(K,K) ) )
-               END IF
-C
-               SCALOC = ONE
-               IF( TEMP.LT.SMIN ) THEN
-                  TEMP  = SMIN
-                  INFOM = 1
-               END IF
-               DR = ABS( R(K,K) )
-               IF( TEMP.LT.ONE .AND. DR.GT.ONE ) THEN
-                  IF( DR.GT.BIGNUM*TEMP )
-     $               SCALOC = ONE / DR
-               END IF
-               ALPHA = SIGN( TEMP, R(K,K) )
-               R(K,K) = R(K,K)/ALPHA
-               IF( SCALOC.NE.ONE ) THEN
-C
-                  DO 60 J = 1, N
-                     CALL DSCAL( J, SCALOC, R(1,J), 1 )
-   60             CONTINUE
-C
-                  SCALE = SCALE*SCALOC
-               END IF
-C
-C              If we are not at the end of  S  then set up and solve
-C              equation (5.14) or (10.16).  ksize is the order of the
-C              remainder of  S.  k1 and k2 point to the start of vectors
-C              in  DWORK.
-C
-               IF ( KOUNT.LE.N ) THEN
-                  KSIZE = N - K
-                  K1 = KSIZE + 1
-                  K2 = KSIZE + K1
-C
-C                 Form the right-hand side in DWORK( 1 ),...,
-C                 DWORK( n - k ).
-C
-                  CALL DCOPY( KSIZE, R(K,K+1), LDR, DWORK, 1 )
-                  CALL DSCAL( KSIZE, -ALPHA, DWORK, 1 )
-                  IF ( CONT ) THEN
-                     CALL DAXPY( KSIZE, -R(K,K), S(K,K+1), LDS, DWORK,
-     $                          1 )
-                  ELSE
-                     CALL DAXPY( KSIZE, -S(K,K)*R(K,K), S(K,K+1), LDS,
-     $                          DWORK, 1 )
-                  END IF
-C
-C                 SB03OR solves the Sylvester equations. The solution is
-C                 overwritten on  DWORK.
-C
-                  CALL SB03OR( DISCR, LTRANS, KSIZE, 1, S(K+1,K+1), LDS,
-     $                         S(K,K), 1, DWORK, KSIZE, SCALOC, INFO )
-                  INFOM = MAX( INFO, INFOM )
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 70 J = 1, N
-                        CALL DSCAL( J, SCALOC, R(1,J), 1 )
-   70                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-C
-C                 Copy the solution into the next  ( n - k ) elements
-C                 of  DWORK,  copy the solution back into  R  and copy
-C                 the row of  R  back into  DWORK.
-C
-                  CALL DCOPY( KSIZE, DWORK, 1, DWORK(K1), 1 )
-                  CALL DSWAP( KSIZE, DWORK, 1, R(K,K+1), LDR )
-C
-C                 Now form the matrix  Rhat  of equation (5.15) or
-C                 (10.17), first computing  y  in  DWORK,  and then
-C                 updating  R1.
-C
-                  IF ( CONT ) THEN
-                     CALL DAXPY( KSIZE, -ALPHA, DWORK(K1), 1, DWORK, 1 )
-                  ELSE
-C
-C                    First form  lambda( 1 )*r  and then add in
-C                    alpha*u11*s.
-C
-                     CALL DSCAL( KSIZE, -S(K,K), DWORK, 1 )
-                     CALL DAXPY( KSIZE, ALPHA*R(K,K), S(K,K+1), LDS,
-     $                           DWORK, 1 )
-C
-C                    Now form  alpha*S1'*u,  first multiplying by the
-C                    sub-diagonal of  S1  and then the triangular part
-C                    of  S1,  and add the result in DWORK.
-C
-                     J1 = K + 1
-C
-                     DO 80 J = 1, KSIZE-1
-                        IF ( S(J1+1,J1).NE.ZERO ) DWORK(J)
-     $                         = ALPHA*S(J1+1,J1)*DWORK(K1+J) + DWORK(J)
-                        J1 = J1 + 1
-   80                CONTINUE
-C
-                     CALL DTRMV( 'Upper', 'Transpose', 'Non-unit',
-     $                           KSIZE, S(K+1,K+1), LDS, DWORK(K1), 1 )
-                     CALL DAXPY( KSIZE, ALPHA, DWORK(K1), 1, DWORK, 1 )
-                  END IF
-                  CALL MB04OD( 'Full', KSIZE, 0, 1, R(K+1,K+1), LDR,
-     $                         DWORK, 1, DWORK, 1, DWORK, 1, DWORK(K2),
-     $                         DWORK(K1) )
-               END IF
-            END IF
-            GO TO 10
-         END IF
-C        END WHILE 10
-C
-      ELSE
-C
-C        Case op(M) = M'.
-C
-         KOUNT = N
-C
-   90    CONTINUE
-C        WHILE( KOUNT.GE.1 )LOOP
-         IF ( KOUNT.GE.1 ) THEN
-            K = KOUNT
-            IF ( KOUNT.EQ.1 ) THEN
-               TBYT  = .FALSE.
-               KOUNT = KOUNT - 1
-            ELSE IF ( S(K,K-1).EQ.ZERO ) THEN
-               TBYT  = .FALSE.
-               KOUNT = KOUNT - 1
-            ELSE
-               TBYT = .TRUE.
-               K = K - 1
-               IF ( K.GT.1 ) THEN
-                  IF ( S(K,K-1).NE.ZERO ) THEN
-                     INFO = 3
-                     RETURN
-                  END IF
-               END IF
-               KOUNT = KOUNT - 2
-            END IF
-            IF ( TBYT ) THEN
-C
-C              Solve the two-by-two Lyapunov equation corresponding to
-C              (6.1) or (10.19), using the routine SB03OY.
-C
-               B(1,1) = S(K,K)
-               B(2,1) = S(K+1,K)
-               B(1,2) = S(K,K+1)
-               B(2,2) = S(K+1,K+1)
-               U(1,1) = R(K,K)
-               U(1,2) = R(K,K+1)
-               U(2,2) = R(K+1,K+1)
-C
-               CALL SB03OY( DISCR, LTRANS, ISGN, B, 2, U, 2, A, 2,
-     $                      SCALOC, INFO )
-               IF ( INFO.GT.1 )
-     $            RETURN
-               INFOM = MAX( INFO, INFOM )
-               IF( SCALOC.NE.ONE ) THEN
-C
-                  DO 100 J = 1, N
-                     CALL DSCAL( J, SCALOC, R(1,J), 1 )
-  100             CONTINUE
-C
-                  SCALE = SCALE*SCALOC
-               END IF
-               R(K,K)     = U(1,1)
-               R(K,K+1)   = U(1,2)
-               R(K+1,K+1) = U(2,2)
-C
-C              If we are not at the front of S then set up and solve
-C              equation corresponding to (6.2) or (10.20).
-C
-C              Note that  SB03OY  returns  ( inv( u11 )*s11*u11 ) in  B
-C              and returns scaled alpha, alpha = inv( u11 )*r11, in  A.
-C              ksize is the order of the remainder leading part of  S.
-C              k1, k2 and k3 point to the start of vectors in  DWORK.
-C
-               IF ( KOUNT.GE.1 ) THEN
-                  KSIZE = K - 1
-                  K1 = KSIZE + 1
-                  K2 = KSIZE + K1
-                  K3 = KSIZE + K2
-C
-C                 Form the right-hand side of equations corresponding to
-C                 (6.2) or (10.20), the first column in DWORK( 1 ) ,...,
-C                 DWORK( k - 1 ) the second in DWORK( k ) ,...,
-C                 DWORK( 2*( k - 1 ) ).
-C
-                  CALL DCOPY( KSIZE, R(1,K), 1, DWORK, 1 )
-                  CALL DCOPY( KSIZE, R(1,K+1), 1, DWORK(K1), 1 )
-                  CALL DTRMM( 'Right', 'Upper', 'Transpose', 'Non-unit',
-     $                        KSIZE, 2, -ONE, A, 2, DWORK, KSIZE )
-                  IF ( CONT ) THEN
-                     CALL DAXPY( KSIZE, -R(K,K), S(1,K), 1, DWORK, 1 )
-                     CALL DAXPY( KSIZE, -R(K,K+1), S(1,K), 1, DWORK(K1),
-     $                           1 )
-                     CALL DAXPY( KSIZE, -R(K+1,K+1), S(1,K+1), 1,
-     $                           DWORK(K1), 1 )
-                  ELSE
-                     CALL DAXPY( KSIZE, -( R(K,K)*B(1,1) + R(K,K+1)
-     $                           *B(1,2) ), S(1,K), 1, DWORK, 1 )
-                     CALL DAXPY( KSIZE, -R(K+1,K+1)*B(1,2), S(1,K+1), 1,
-     $                           DWORK, 1 )
-                     CALL DAXPY( KSIZE, -( R(K,K)*B(2,1) + R(K,K+1)
-     $                           *B(2,2) ), S(1,K), 1, DWORK(K1), 1 )
-                     CALL DAXPY( KSIZE, -R(K+1,K+1)*B(2,2), S(1,K+1), 1,
-     $                           DWORK(K1), 1 )
-                  END IF
-C
-C                 SB03OR  solves the Sylvester equations. The solution
-C                 is overwritten on DWORK.
-C
-                  CALL SB03OR( DISCR, LTRANS, KSIZE, 2, S, LDS, B, 2,
-     $                         DWORK, KSIZE, SCALOC, INFO )
-                  INFOM = MAX( INFO, INFOM )
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 110 J = 1, N
-                        CALL DSCAL( J, SCALOC, R(1,J), 1 )
-  110                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-C
-C                 Copy the solution into the next  2*( k - 1 ) elements
-C                 of  DWORK.
-C
-                  CALL DCOPY( 2*KSIZE, DWORK, 1, DWORK(K2), 1 )
-C
-C                 Now form the matrix  Rhat  of equation corresponding
-C                 to (6.4) or (10.22) (corrected version).
-C
-                  IF ( CONT ) THEN
-C
-C                    Swap the two columns of R with DWORK.
-C
-                     CALL DSWAP( KSIZE, DWORK, 1, R(1,K), 1 )
-                     CALL DSWAP( KSIZE, DWORK(K1), 1, R(1,K+1), 1 )
-C
-C                    1st column:
-C
-                     CALL DAXPY( KSIZE, -A(1,1), DWORK(K2), 1, DWORK,
-     $                           1 )
-C
-C                    2nd column:
-C
-                     CALL DAXPY( KSIZE, -A(1,2), DWORK(K2), 1,
-     $                           DWORK(K1), 1 )
-                     CALL DAXPY( KSIZE, -A(2,2), DWORK(K3), 1,
-     $                           DWORK(K1), 1 )
-                  ELSE
-C
-C                    Form  v = S1*u + s*u11, overwriting  v  on DWORK.
-C
-C                    Compute  S1*u,  first multiplying by the triangular
-C                    part of  S1.
-C
-                     CALL DTRMM( 'Left', 'Upper', 'No transpose',
-     $                           'Non-unit', KSIZE, 2, ONE, S, LDS,
-     $                           DWORK, KSIZE )
-C
-C                    Then multiply by the subdiagonal of  S1  and add in
-C                    to the above result.
-C
-                     J1 = K1
-C
-                     DO 120 J = 2, KSIZE
-                        J1 = J1 + 1
-                        IF ( S(J,J-1).NE.ZERO ) THEN
-                           DWORK(J)  = S(J,J-1)*DWORK(K2+J-2) + DWORK(J)
-                           DWORK(J1) = S(J,J-1)*DWORK(K3+J-2) +
-     $                                 DWORK(J1)
-                        END IF
-  120                CONTINUE
-C
-C                    Add in s*u11.
-C
-                     CALL DAXPY( KSIZE, R(K,K), S(1,K), 1, DWORK, 1 )
-                     CALL DAXPY( KSIZE, R(K,K+1), S(1,K), 1, DWORK(K1),
-     $                           1 )
-                     CALL DAXPY( KSIZE, R(K+1,K+1), S(1,K+1), 1,
-     $                           DWORK(K1), 1 )
-C
-C                    Next recover r from R, swapping r with u.
-C
-                     CALL DSWAP( KSIZE, DWORK(K2), 1, R(1,K), 1 )
-                     CALL DSWAP( KSIZE, DWORK(K3), 1, R(1,K+1), 1 )
-C
-C                    Now we perform the QL factorization.
-C
-C                    ( a' ) = Q*( t ),
-C                    ( b' )
-C
-C                    and form
-C
-C                    ( p' ) = Q'*( r' ).
-C                    ( y' )      ( v' )
-C
-C                    y  is then the correct vector to use in the
-C                    relation corresponding to (10.22).
-C                    Note that  a  is upper triangular and that  t  and
-C                    p  are not required.
-C
-                     CALL DLARFG( 3, A(2,2), B(2,1), 2, TAU1 )
-                     V1  = B(2,1)
-                     T1  = TAU1*V1
-                     V2  = B(2,2)
-                     T2  = TAU1*V2
-                     SUM = A(1,2) + V1*B(1,1) + V2*B(1,2)
-                     B(1,1) = B(1,1) - SUM*T1
-                     B(1,2) = B(1,2) - SUM*T2
-                     CALL DLARFG( 3, A(1,1), B(1,1), 2, TAU2 )
-                     V3 = B(1,1)
-                     T3 = TAU2*V3
-                     V4 = B(1,2)
-                     T4 = TAU2*V4
-                     J1 = K1
-                     J2 = K2
-                     J3 = K3
-C
-                     DO 130 J = 1, KSIZE
-                        SUM = DWORK(J3) + V1*DWORK(J) + V2*DWORK(J1)
-                        D1  = DWORK(J)  - SUM*T1
-                        D2  = DWORK(J1) - SUM*T2
-                        SUM = DWORK(J2) + V3*D1 + V4*D2
-                        DWORK(J)  =  D1 - SUM*T3
-                        DWORK(J1) =  D2 - SUM*T4
-                        J1 = J1 + 1
-                        J2 = J2 + 1
-                        J3 = J3 + 1
-  130                CONTINUE
-C
-                  END IF
-C
-C                 Now update  R1  to give  Rhat.
-C
-                  CALL MB04ND( 'Full', KSIZE, 0, 2, R, LDR, DWORK,
-     $                         KSIZE, DWORK, 1, DWORK, 1, DWORK(K2),
-     $                         DWORK(K3) )
-               END IF
-            ELSE
-C
-C              1-by-1 block.
-C
-C              Make sure S is stable or convergent and find u11 in
-C              equation corresponding to (5.13) or (10.15).
-C
-               IF ( DISCR ) THEN
-                  ABSSKK = ABS( S(K,K) )
-                  IF ( ( ABSSKK - ONE ).GE.ZERO ) THEN
-                     INFO = 2
-                     RETURN
-                  END IF
-                  TEMP = SQRT( ( ONE - ABSSKK )*( ONE + ABSSKK ) )
-               ELSE
-                  IF ( S(K,K).GE.ZERO ) THEN
-                     INFO = 2
-                     RETURN
-                  END IF
-                  TEMP = SQRT( ABS( TWO*S(K,K) ) )
-               END IF
-C
-               SCALOC = ONE
-               IF( TEMP.LT.SMIN ) THEN
-                  TEMP  = SMIN
-                  INFOM = 1
-               END IF
-               DR = ABS( R(K,K) )
-               IF( TEMP.LT.ONE .AND. DR.GT.ONE ) THEN
-                  IF( DR.GT.BIGNUM*TEMP )
-     $               SCALOC = ONE / DR
-               END IF
-               ALPHA = SIGN( TEMP, R(K,K) )
-               R(K,K) = R(K,K)/ALPHA
-               IF( SCALOC.NE.ONE ) THEN
-C
-                  DO 140 J = 1, N
-                     CALL DSCAL( J, SCALOC, R(1,J), 1 )
-  140             CONTINUE
-C
-                  SCALE = SCALE*SCALOC
-               END IF
-C
-C              If we are not at the front of  S  then set up and solve
-C              equation corresponding to (5.14) or (10.16).  ksize is
-C              the order of the remainder leading part of  S.  k1 and k2
-C              point to the start of vectors in  DWORK.
-C
-               IF ( KOUNT.GE.1 ) THEN
-                  KSIZE = K - 1
-                  K1 = KSIZE + 1
-                  K2 = KSIZE + K1
-C
-C                 Form the right-hand side in DWORK( 1 ),...,
-C                 DWORK( k - 1 ).
-C
-                  CALL DCOPY( KSIZE, R(1,K), 1, DWORK, 1 )
-                  CALL DSCAL( KSIZE, -ALPHA, DWORK, 1 )
-                  IF ( CONT ) THEN
-                     CALL DAXPY( KSIZE, -R(K,K), S(1,K), 1, DWORK, 1 )
-                  ELSE
-                     CALL DAXPY( KSIZE, -S(K,K)*R(K,K), S(1,K), 1,
-     $                          DWORK, 1 )
-                  END IF
-C
-C                 SB03OR solves the Sylvester equations. The solution is
-C                 overwritten on  DWORK.
-C
-                  CALL SB03OR( DISCR, LTRANS, KSIZE, 1, S, LDS, S(K,K),
-     $                         1, DWORK, KSIZE, SCALOC, INFO )
-                  INFOM = MAX( INFO, INFOM )
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 150 J = 1, N
-                        CALL DSCAL( J, SCALOC, R(1,J), 1 )
-  150                CONTINUE
-C
-                     SCALE = SCALE*SCALOC
-                  END IF
-C
-C                 Copy the solution into the next  ( k - 1 ) elements
-C                 of  DWORK,  copy the solution back into  R  and copy
-C                 the column of  R  back into  DWORK.
-C
-                  CALL DCOPY( KSIZE, DWORK, 1, DWORK(K1), 1 )
-                  CALL DSWAP( KSIZE, DWORK, 1, R(1,K), 1 )
-C
-C                 Now form the matrix  Rhat  of equation corresponding
-C                 to (5.15) or (10.17), first computing  y  in  DWORK,
-C                 and then updating  R1.
-C
-                  IF ( CONT ) THEN
-                     CALL DAXPY( KSIZE, -ALPHA, DWORK(K1), 1, DWORK, 1 )
-                  ELSE
-C
-C                    First form  lambda( 1 )*r  and then add in
-C                    alpha*u11*s.
-C
-                     CALL DSCAL( KSIZE, -S(K,K), DWORK, 1 )
-                     CALL DAXPY( KSIZE, ALPHA*R(K,K), S(1,K), 1, DWORK,
-     $                           1 )
-C
-C                    Now form  alpha*S1*u,  first multiplying by the
-C                    sub-diagonal of  S1  and then the triangular part
-C                    of  S1,  and add the result in DWORK.
-C
-                     DO 160 J = 2, KSIZE
-                        IF ( S(J,J-1).NE.ZERO ) DWORK(J)
-     $                         = ALPHA*S(J,J-1)*DWORK(K1+J-2) + DWORK(J)
-  160                CONTINUE
-C
-                     CALL DTRMV( 'Upper', 'No transpose', 'Non-unit',
-     $                           KSIZE, S, LDS, DWORK(K1), 1 )
-                     CALL DAXPY( KSIZE, ALPHA, DWORK(K1), 1, DWORK, 1 )
-                  END IF
-                  CALL MB04ND( 'Full', KSIZE, 0, 1, R, LDR, DWORK,
-     $                         KSIZE, DWORK, 1, DWORK, 1, DWORK(K2),
-     $                         DWORK(K1) )
-               END IF
-            END IF
-            GO TO 90
-         END IF
-C        END WHILE 90
-C
-      END IF
-      INFO = INFOM
-      RETURN
-C *** Last line of SB03OT ***
-      END
--- a/extra/control-devel/src/SB03OU.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,410 +0,0 @@
-      SUBROUTINE SB03OU( DISCR, LTRANS, N, M, A, LDA, B, LDB, TAU, U,
-     $                   LDU, SCALE, DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To solve for X = op(U)'*op(U) either the stable non-negative
-C     definite continuous-time Lyapunov equation
-C                                   2
-C        op(A)'*X + X*op(A) = -scale *op(B)'*op(B)                   (1)
-C
-C     or the convergent non-negative definite discrete-time Lyapunov
-C     equation
-C                                   2
-C        op(A)'*X*op(A) - X = -scale *op(B)'*op(B)                   (2)
-C
-C     where op(K) = K or K' (i.e., the transpose of the matrix K), A is
-C     an N-by-N matrix in real Schur form, op(B) is an M-by-N matrix,
-C     U is an upper triangular matrix containing the Cholesky factor of
-C     the solution matrix X, X = op(U)'*op(U), and scale is an output
-C     scale factor, set less than or equal to 1 to avoid overflow in X.
-C     If matrix B has full rank then the solution matrix X will be
-C     positive-definite and hence the Cholesky factor U will be
-C     nonsingular, but if B is rank deficient then X may only be
-C     positive semi-definite and U will be singular.
-C
-C     In the case of equation (1) the matrix A must be stable (that
-C     is, all the eigenvalues of A must have negative real parts),
-C     and for equation (2) the matrix A must be convergent (that is,
-C     all the eigenvalues of A must lie inside the unit circle).
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DISCR   LOGICAL
-C             Specifies the type of Lyapunov equation to be solved as
-C             follows:
-C             = .TRUE. :  Equation (2), discrete-time case;
-C             = .FALSE.:  Equation (1), continuous-time case.
-C
-C     LTRANS  LOGICAL
-C             Specifies the form of op(K) to be used, as follows:
-C             = .FALSE.:  op(K) = K    (No transpose);
-C             = .TRUE. :  op(K) = K**T (Transpose).
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix A and the number of columns in
-C             matrix op(B).  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of rows in matrix op(B).  M >= 0.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,N)
-C             The leading N-by-N upper Hessenberg part of this array
-C             must contain a real Schur form matrix S. The elements
-C             below the upper Hessenberg part of the array A are not
-C             referenced. The 2-by-2 blocks must only correspond to
-C             complex conjugate pairs of eigenvalues (not to real
-C             eigenvalues).
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,N)
-C             if LTRANS = .FALSE., and dimension (LDB,M), if
-C             LTRANS = .TRUE..
-C             On entry, if LTRANS = .FALSE., the leading M-by-N part of
-C             this array must contain the coefficient matrix B of the
-C             equation.
-C             On entry, if LTRANS = .TRUE., the leading N-by-M part of
-C             this array must contain the coefficient matrix B of the
-C             equation.
-C             On exit, if LTRANS = .FALSE., the leading
-C             MIN(M,N)-by-MIN(M,N) upper triangular part of this array
-C             contains the upper triangular matrix R (as defined in
-C             METHOD), and the M-by-MIN(M,N) strictly lower triangular
-C             part together with the elements of the array TAU are
-C             overwritten by details of the matrix P (also defined in
-C             METHOD). When M < N, columns (M+1),...,N of the array B
-C             are overwritten by the matrix Z (see METHOD).
-C             On exit, if LTRANS = .TRUE., the leading
-C             MIN(M,N)-by-MIN(M,N) upper triangular part of
-C             B(1:N,M-N+1), if M >= N, or of B(N-M+1:N,1:M), if M < N,
-C             contains the upper triangular matrix R (as defined in
-C             METHOD), and the remaining elements (below the diagonal
-C             of R) together with the elements of the array TAU are
-C             overwritten by details of the matrix P (also defined in
-C             METHOD). When M < N, rows 1,...,(N-M) of the array B
-C             are overwritten by the matrix Z (see METHOD).
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.
-C             LDB >= MAX(1,M), if LTRANS = .FALSE.,
-C             LDB >= MAX(1,N), if LTRANS = .TRUE..
-C
-C     TAU     (output) DOUBLE PRECISION array of dimension (MIN(N,M))
-C             This array contains the scalar factors of the elementary
-C             reflectors defining the matrix P.
-C
-C     U       (output) DOUBLE PRECISION array of dimension (LDU,N)
-C             The leading N-by-N upper triangular part of this array
-C             contains the Cholesky factor of the solution matrix X of
-C             the problem, X = op(U)'*op(U).
-C             The array U may be identified with B in the calling
-C             statement, if B is properly dimensioned, and the
-C             intermediate results returned in B are not needed.
-C
-C     LDU     INTEGER
-C             The leading dimension of array U.  LDU >= MAX(1,N).
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor, scale, set less than or equal to 1 to
-C             prevent the solution overflowing.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, or INFO = 1, DWORK(1) returns the
-C             optimal value of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK. LDWORK >= MAX(1,4*N).
-C             For optimum performance LDWORK should sometimes 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 Lyapunov equation is (nearly) singular
-C                   (warning indicator);
-C                   if DISCR = .FALSE., this means that while the matrix
-C                   A has computed eigenvalues with negative real parts,
-C                   it is only just stable in the sense that small
-C                   perturbations in A can make one or more of the
-C                   eigenvalues have a non-negative real part;
-C                   if DISCR = .TRUE., this means that while the matrix
-C                   A has computed eigenvalues inside the unit circle,
-C                   it is nevertheless only just convergent, in the
-C                   sense that small perturbations in A can make one or
-C                   more of the eigenvalues lie outside the unit circle;
-C                   perturbed values were used to solve the equation
-C                   (but the matrix A is unchanged);
-C             = 2:  if matrix A is not stable (that is, one or more of
-C                   the eigenvalues of A has a non-negative real part),
-C                   if DISCR = .FALSE., or not convergent (that is, one
-C                   or more of the eigenvalues of A lies outside the
-C                   unit circle), if DISCR = .TRUE.;
-C             = 3:  if matrix A has two or more consecutive non-zero
-C                   elements on the first sub-diagonal, so that there is
-C                   a block larger than 2-by-2 on the diagonal;
-C             = 4:  if matrix A has a 2-by-2 diagonal block with real
-C                   eigenvalues instead of a complex conjugate pair.
-C
-C     METHOD
-C
-C     The method used by the routine is based on the Bartels and
-C     Stewart method [1], except that it finds the upper triangular
-C     matrix U directly without first finding X and without the need
-C     to form the normal matrix op(B)'*op(B) [2].
-C
-C     If LTRANS = .FALSE., the matrix B is factored as
-C
-C        B = P ( R ),  M >= N,   B = P ( R  Z ),  M < N,
-C              ( 0 )
-C
-C     (QR factorization), where P is an M-by-M orthogonal matrix and
-C     R is a square upper triangular matrix.
-C
-C     If LTRANS = .TRUE., the matrix B is factored as
-C
-C        B = ( 0  R ) P,  M >= N,  B = ( Z ) P,  M < N,
-C                                      ( R )
-C
-C     (RQ factorization), where P is an M-by-M orthogonal matrix and
-C     R is a square upper triangular matrix.
-C
-C     These factorizations are used to solve the continuous-time
-C     Lyapunov equation in the canonical form
-C                                                        2
-C       op(A)'*op(U)'*op(U) + op(U)'*op(U)*op(A) = -scale *op(F)'*op(F),
-C
-C     or the discrete-time Lyapunov equation in the canonical form
-C                                                        2
-C       op(A)'*op(U)'*op(U)*op(A) - op(U)'*op(U) = -scale *op(F)'*op(F),
-C
-C     where U and F are N-by-N upper triangular matrices, and
-C
-C        F = R,                                  if M >= N, or
-C
-C        F = ( R ),    if LTRANS = .FALSE.,  or
-C            ( 0 )
-C
-C        F = ( 0  Z ), if LTRANS = .TRUE.,       if M < N.
-C            ( 0  R )
-C
-C     The canonical equation is solved for U.
-C
-C     REFERENCES
-C
-C     [1] Bartels, R.H. and Stewart, G.W.
-C         Solution of the matrix equation  A'X + XB = C.
-C         Comm. A.C.M., 15, pp. 820-826, 1972.
-C
-C     [2] Hammarling, S.J.
-C         Numerical solution of the stable, non-negative definite
-C         Lyapunov equation.
-C         IMA J. Num. Anal., 2, pp. 303-325, 1982.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations and is backward stable.
-C
-C     FURTHER COMMENTS
-C
-C     The Lyapunov equation may be very ill-conditioned. In particular,
-C     if A is only just stable (or convergent) then the Lyapunov
-C     equation will be ill-conditioned. "Large" elements in U relative
-C     to those of A and B, or a "small" value for scale, are symptoms
-C     of ill-conditioning. A condition estimate can be computed using
-C     SLICOT Library routine SB03MD.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, May 1997.
-C     Supersedes Release 2.0 routine SB03CZ by Sven Hammarling,
-C     NAG Ltd, United Kingdom.
-C     Partly based on routine PLYAPS by A. Varga, University of Bochum,
-C     May 1992.
-C
-C     REVISIONS
-C
-C     Dec. 1997, April 1998, May 1999.
-C
-C     KEYWORDS
-C
-C     Lyapunov equation, orthogonal transformation, real Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      LOGICAL           DISCR, LTRANS
-      INTEGER           INFO, LDA, LDB, LDU, LDWORK, M, N
-      DOUBLE PRECISION  SCALE
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), DWORK(*), TAU(*), U(LDU,*)
-C     .. Local Scalars ..
-      INTEGER           I, J, K, L, MN, WRKOPT
-C     .. External Subroutines ..
-      EXTERNAL          DCOPY, DGEQRF, DGERQF, DLACPY, DLASET, SB03OT,
-     $                  XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX, MIN
-C     .. Executable Statements ..
-C
-      INFO = 0
-C
-C     Test the input scalar arguments.
-C
-      IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( ( LDB.LT.MAX( 1, M ) .AND. .NOT.LTRANS ) .OR.
-     $         ( LDB.LT.MAX( 1, N ) .AND.      LTRANS ) ) THEN
-         INFO = -8
-      ELSE IF( LDU.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDWORK.LT.MAX( 1, 4*N ) ) THEN
-         INFO = -14
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB03OU', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      MN = MIN( N, M )
-      IF ( MN.EQ.0 ) THEN
-         SCALE = ONE
-         DWORK(1) = ONE
-         RETURN
-      END IF
-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 ( LTRANS ) THEN
-C
-C        Case op(K) = K'.
-C
-C        Perform the RQ factorization of B.
-C        Workspace: need   N;
-C                   prefer N*NB.
-C
-         CALL DGERQF( N, M, B, LDB, TAU, DWORK, LDWORK, INFO )
-C
-C        The triangular matrix F is constructed in the array U so that
-C        U can share the same memory as B.
-C
-         IF ( M.GE.N ) THEN
-            CALL DLACPY( 'Upper', MN, N, B(1,M-N+1), LDB, U, LDU )
-         ELSE
-C
-            DO 10 I = M, 1, -1
-               CALL DCOPY( N-M+I, B(1,I), 1, U(1,N-M+I), 1 )
-   10       CONTINUE
-C
-            CALL DLASET( 'Full', N, N-M, ZERO, ZERO, U, LDU )
-         END IF
-      ELSE
-C
-C        Case op(K) = K.
-C
-C        Perform the QR factorization of B.
-C        Workspace: need   N;
-C                   prefer N*NB.
-C
-         CALL DGEQRF( M, N, B, LDB, TAU, DWORK, LDWORK, INFO )
-         CALL DLACPY( 'Upper', MN, N, B, LDB, U, LDU )
-         IF ( M.LT.N )
-     $      CALL DLASET( 'Upper', N-M, N-M, ZERO, ZERO, U(M+1,M+1),
-     $                   LDU )
-      END IF
-      WRKOPT = DWORK(1)
-C
-C     Solve the canonical Lyapunov equation
-C                                                      2
-C     op(A)'*op(U)'*op(U) + op(U)'*op(U)*op(A) = -scale *op(F)'*op(F),
-C
-C     or
-C                                                      2
-C     op(A)'*op(U)'*op(U)*op(A) - op(U)'*op(U) = -scale *op(F)'*op(F)
-C
-C     for U.
-C
-      CALL SB03OT( DISCR, LTRANS, N, A, LDA, U, LDU, SCALE, DWORK,
-     $             INFO )
-      IF ( INFO.NE.0 .AND. INFO.NE.1 )
-     $   RETURN
-C
-C     Make the diagonal elements of U non-negative.
-C
-      IF ( LTRANS ) THEN
-C
-         DO 30 J = 1, N
-            IF ( U(J,J).LT.ZERO ) THEN
-C
-               DO 20 I = 1, J
-                  U(I,J) = -U(I,J)
-   20          CONTINUE
-C
-            END IF
-   30    CONTINUE
-C
-      ELSE
-         K = 1
-C
-         DO 50 J = 1, N
-            DWORK(K) = U(J,J)
-            L = 1
-C
-            DO 40 I = 1, J
-               IF ( DWORK(L).LT.ZERO ) U(I,J) = -U(I,J)
-               L = L + 1
-   40       CONTINUE
-C
-            K = K + 1
-   50    CONTINUE
-C
-      END IF
-C
-      DWORK(1) = MAX( WRKOPT, 4*N )
-      RETURN
-C *** Last line of SB03OU ***
-      END
--- a/extra/control-devel/src/SB03OV.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,105 +0,0 @@
-      SUBROUTINE SB03OV( A, B, C, S )
-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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To construct a complex plane rotation such that, for a complex
-C     number  a  and a real number  b,
-C
-C        ( conjg( c )  s )*( a ) = ( d ),
-C        (       -s    c ) ( b )   ( 0 )
-C
-C     where  d  is always real and is overwritten on  a,  so that on
-C     return the imaginary part of  a  is zero.  b  is unaltered.
-C
-C     This routine has A and C declared as REAL, because it is intended
-C     for use within a real Lyapunov solver and the REAL declarations
-C     mean that a standard Fortran DOUBLE PRECISION version may be
-C     readily constructed.  However A and C could safely be declared
-C     COMPLEX in the calling program, although some systems may give a
-C     type mismatch warning.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (2)
-C             On entry, A(1) and A(2) must contain the real and
-C             imaginary part, respectively, of the complex number a.
-C             On exit, A(1) contains the real part of d, and A(2) is
-C             set to zero.
-C
-C     B       (input) DOUBLE PRECISION
-C             The real number b.
-C
-C     C       (output) DOUBLE PRECISION array, dimension (2)
-C             C(1) and C(2) contain the real and imaginary part,
-C             respectively, of the complex number c, the cosines of
-C             the plane rotation.
-C
-C     S       (output) DOUBLE PRECISION
-C             The real number s, the sines of the plane rotation.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Aug. 1997.
-C     Supersedes Release 2.0 routine SB03CV by Sven Hammarling,
-C     NAG Ltd., United Kingdom, May 1985.
-C
-C     REVISIONS
-C
-C     Dec. 1997.
-C
-C     KEYWORDS
-C
-C     Lyapunov equation, orthogonal transformation.
-C
-C     *****************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      DOUBLE PRECISION  B, S
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(2), C(2)
-C     .. Local Scalars ..
-      DOUBLE PRECISION  D
-C     .. External Functions ..
-      DOUBLE PRECISION  DLAPY3
-      EXTERNAL          DLAPY3
-C     .. Executable Statements ..
-C
-      D = DLAPY3( A(1), A(2), B )
-      IF ( D.EQ.ZERO ) THEN
-         C(1) = ONE
-         C(2) = ZERO
-         S = ZERO
-      ELSE
-         C(1) = A(1)/D
-         C(2) = A(2)/D
-         S = B/D
-         A(1) = D
-         A(2) = ZERO
-      END IF
-C
-      RETURN
-C *** Last line of SB03OV ***
-      END
--- a/extra/control-devel/src/SB03OY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,693 +0,0 @@
-      SUBROUTINE SB03OY( DISCR, LTRANS, ISGN, S, LDS, R, LDR, A, LDA,
-     $                   SCALE, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To solve for the Cholesky factor  U  of  X,
-C
-C        op(U)'*op(U) = X,
-C
-C     where  U  is a two-by-two upper triangular matrix, either the
-C     continuous-time two-by-two Lyapunov equation
-C                                         2
-C         op(S)'*X + X*op(S) = -ISGN*scale *op(R)'*op(R),
-C
-C     when DISCR = .FALSE., or the discrete-time two-by-two Lyapunov
-C     equation
-C                                         2
-C         op(S)'*X*op(S) - X = -ISGN*scale *op(R)'*op(R),
-C
-C     when DISCR = .TRUE., where op(K) = K or K' (i.e., the transpose of
-C     the matrix K),  S  is a two-by-two matrix with complex conjugate
-C     eigenvalues,  R  is a two-by-two upper triangular matrix,
-C     ISGN = -1 or 1,  and  scale  is an output scale factor, set less
-C     than or equal to 1 to avoid overflow in  X.  The routine also
-C     computes two matrices, B and A, so that
-C                                   2
-C        B*U = U*S  and  A*U = scale *R,  if  LTRANS = .FALSE.,  or
-C                                   2
-C        U*B = S*U  and  U*A = scale *R,  if  LTRANS = .TRUE.,
-C     which are used by the general Lyapunov solver.
-C     In the continuous-time case  ISGN*S  must be stable, so that its
-C     eigenvalues must have strictly negative real parts.
-C     In the discrete-time case  S  must be convergent if ISGN = 1, that
-C     is, its eigenvalues must have moduli less than unity, or  S  must
-C     be completely divergent if ISGN = -1, that is, its eigenvalues
-C     must have moduli greater than unity.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DISCR   LOGICAL
-C             Specifies the equation to be solved:       2
-C             = .FALSE.: op(S)'*X + X*op(S) = -ISGN*scale *op(R)'*op(R);
-C                                                        2
-C             = .TRUE. : op(S)'*X*op(S) - X = -ISGN*scale *op(R)'*op(R).
-C
-C     LTRANS  LOGICAL
-C             Specifies the form of op(K) to be used, as follows:
-C             = .FALSE.:  op(K) = K    (No transpose);
-C             = .TRUE. :  op(K) = K**T (Transpose).
-C
-C     ISGN    INTEGER
-C             Specifies the sign of the equation as described before.
-C             ISGN may only be 1 or -1.
-C
-C     Input/Output Parameters
-C
-C     S       (input/output) DOUBLE PRECISION array, dimension (LDS,2)
-C             On entry, S must contain a 2-by-2 matrix.
-C             On exit, S contains a 2-by-2 matrix B such that B*U = U*S,
-C             if LTRANS = .FALSE., or U*B = S*U, if LTRANS = .TRUE..
-C             Notice that if U is nonsingular then
-C               B = U*S*inv( U ),  if LTRANS = .FALSE.
-C               B = inv( U )*S*U,  if LTRANS = .TRUE..
-C
-C     LDS     INTEGER
-C             The leading dimension of array S.  LDS >= 2.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,2)
-C             On entry, R must contain a 2-by-2 upper triangular matrix.
-C             The element R( 2, 1 ) is not referenced.
-C             On exit, R contains U, the 2-by-2 upper triangular
-C             Cholesky factor of the solution X, X = op(U)'*op(U).
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= 2.
-C
-C     A       (output) DOUBLE PRECISION array, dimension (LDA,2)
-C             A contains a 2-by-2 upper triangular matrix A satisfying
-C             A*U/scale = scale*R, if LTRANS = .FALSE., or
-C             U*A/scale = scale*R, if LTRANS = .TRUE..
-C             Notice that if U is nonsingular then
-C               A = scale*scale*R*inv( U ),  if LTRANS = .FALSE.
-C               A = scale*scale*inv( U )*R,  if LTRANS = .TRUE..
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= 2.
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor, scale, set less than or equal to 1 to
-C             prevent the solution overflowing.
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             = 0:  successful exit;
-C             = 1:  if the Lyapunov equation is (nearly) singular
-C                   (warning indicator);
-C                   if DISCR = .FALSE., this means that while the
-C                   matrix S has computed eigenvalues with negative real
-C                   parts, it is only just stable in the sense that
-C                   small perturbations in S can make one or more of the
-C                   eigenvalues have a non-negative real part;
-C                   if DISCR = .TRUE., this means that while the
-C                   matrix S has computed eigenvalues inside the unit
-C                   circle, it is nevertheless only just convergent, in
-C                   the sense that small perturbations in S can make one
-C                   or more of the eigenvalues lie outside the unit
-C                   circle;
-C                   perturbed values were used to solve the equation
-C                   (but the matrix S is unchanged);
-C             = 2:  if DISCR = .FALSE., and ISGN*S is not stable or
-C                   if DISCR = .TRUE., ISGN = 1 and S is not convergent
-C                   or if DISCR = .TRUE., ISGN = -1 and S is not
-C                   completely divergent;
-C             = 4:  if S has real eigenvalues.
-C
-C     NOTE: In the interests of speed, this routine does not check all
-C           inputs for errors.
-C
-C     METHOD
-C
-C     The LAPACK scheme for solving 2-by-2 Sylvester equations is
-C     adapted for 2-by-2 Lyapunov equations, but directly computing the
-C     Cholesky factor of the solution.
-C
-C     REFERENCES
-C
-C     [1] Hammarling S. J.
-C         Numerical solution of the stable, non-negative definite
-C         Lyapunov equation.
-C         IMA J. Num. Anal., 2, pp. 303-325, 1982.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is backward stable.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Aug. 1997.
-C     Supersedes Release 2.0 routine SB03CY by Sven Hammarling,
-C     NAG Ltd., United Kingdom, November 1986.
-C     Partly based on SB03CY and PLYAP2 by A. Varga, University of
-C     Bochum, May 1992.
-C
-C     REVISIONS
-C
-C     Dec. 1997, April 1998.
-C
-C     KEYWORDS
-C
-C     Lyapunov equation, orthogonal transformation, real Schur form.
-C
-C     *****************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE, TWO, FOUR
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0, TWO = 2.0D0,
-     $                    FOUR = 4.0D0 )
-C     .. Scalar Arguments ..
-      LOGICAL           DISCR, LTRANS
-      INTEGER           INFO, ISGN, LDA, LDR, LDS
-      DOUBLE PRECISION  SCALE
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), R(LDR,*), S(LDS,*)
-C     .. Local Scalars ..
-      DOUBLE PRECISION  ABSB, ABSG, ABST, ALPHA, BIGNUM, E1, E2, EPS,
-     $                  ETA, P1, P3, P3I, P3R, S11, S12, S21, S22,
-     $                  SCALOC, SGN, SMIN, SMLNUM, SNP, SNQ, SNT, TEMPI,
-     $                  TEMPR, V1, V3
-C     .. Local Arrays ..
-      DOUBLE PRECISION  CSP(2), CSQ(2), CST(2), DELTA(2), DP(2), DT(2),
-     $                  G(2), GAMMA(2), P2(2), T(2), TEMP(2), V2(2),
-     $                  X11(2), X12(2), X21(2), X22(2), Y(2)
-C     .. External Functions ..
-      DOUBLE PRECISION  DLAMCH, DLAPY2, DLAPY3
-      EXTERNAL          DLAMCH, DLAPY2, DLAPY3
-C     .. External Subroutines ..
-      EXTERNAL          DLABAD, DLANV2, SB03OV
-C     .. Intrinsic Functions ..
-      INTRINSIC         ABS, MAX, SIGN, SQRT
-C     .. Executable Statements ..
-C
-C     The comments in this routine refer to notation and equation
-C     numbers in sections 6 and 10 of [1].
-C
-C     Find the eigenvalue  lambda = E1 - i*E2  of s11.
-C
-      INFO = 0
-      SGN = ISGN
-      S11 = S(1,1)
-      S12 = S(1,2)
-      S21 = S(2,1)
-      S22 = S(2,2)
-C
-C     Set constants to control overflow.
-C
-      EPS = DLAMCH( 'P' )
-      SMLNUM = DLAMCH( 'S' )
-      BIGNUM = ONE / SMLNUM
-      CALL DLABAD( SMLNUM, BIGNUM )
-      SMLNUM = SMLNUM*FOUR / EPS
-      BIGNUM = ONE / SMLNUM
-C
-      SMIN = MAX( SMLNUM, EPS*MAX( ABS( S11 ), ABS( S12 ),
-     $                             ABS( S21 ), ABS( S22 ) ) )
-      SCALE = ONE
-C
-      CALL DLANV2( S11, S12, S21, S22, TEMPR, TEMPI, E1, E2, CSP, CSQ )
-      IF ( TEMPI.EQ.ZERO ) THEN
-         INFO = 4
-         RETURN
-      END IF
-      ABSB = DLAPY2( E1, E2 )
-      IF ( DISCR ) THEN
-         IF ( SGN*( ABSB - ONE ).GE.ZERO ) THEN
-            INFO = 2
-            RETURN
-         END IF
-      ELSE
-         IF ( SGN*E1.GE.ZERO ) THEN
-            INFO = 2
-            RETURN
-         END IF
-      END IF
-C
-C     Compute the cos and sine that define  Qhat.  The sine is real.
-C
-      TEMP(1) = S(1,1) - E1
-      TEMP(2) = E2
-      IF ( LTRANS ) TEMP(2) = -E2
-      CALL SB03OV( TEMP, S(2,1), CSQ, SNQ )
-C
-C     beta in (6.9) is given by  beta = E1 + i*E2,  compute  t.
-C
-      TEMP(1) = CSQ(1)*S(1,2) - SNQ*S(1,1)
-      TEMP(2) = CSQ(2)*S(1,2)
-      TEMPR   = CSQ(1)*S(2,2) - SNQ*S(2,1)
-      TEMPI   = CSQ(2)*S(2,2)
-      T(1)    = CSQ(1)*TEMP(1) - CSQ(2)*TEMP(2) + SNQ*TEMPR
-      T(2)    = CSQ(1)*TEMP(2) + CSQ(2)*TEMP(1) + SNQ*TEMPI
-C
-      IF ( LTRANS ) THEN
-C                                                         (     -- )
-C        Case op(M) = M'.  Note that the modified  R  is  ( p3  p2 ).
-C                                                         ( 0   p1 )
-C
-C        Compute the cos and sine that define  Phat.
-C
-         TEMP(1) =  CSQ(1)*R(2,2) - SNQ*R(1,2)
-         TEMP(2) = -CSQ(2)*R(2,2)
-         CALL SB03OV( TEMP, -SNQ*R(1,1), CSP, SNP )
-C
-C        Compute p1, p2 and p3 of the relation corresponding to (6.11).
-C
-         P1 = TEMP(1)
-         TEMP(1) =  CSQ(1)*R(1,2) + SNQ*R(2,2)
-         TEMP(2) = -CSQ(2)*R(1,2)
-         TEMPR   =  CSQ(1)*R(1,1)
-         TEMPI   = -CSQ(2)*R(1,1)
-         P2(1)   =  CSP(1)*TEMP(1) - CSP(2)*TEMP(2) + SNP*TEMPR
-         P2(2)   = -CSP(1)*TEMP(2) - CSP(2)*TEMP(1) - SNP*TEMPI
-         P3R     =  CSP(1)*TEMPR   + CSP(2)*TEMPI   - SNP*TEMP(1)
-         P3I     =  CSP(1)*TEMPI   - CSP(2)*TEMPR   - SNP*TEMP(2)
-      ELSE
-C
-C        Case op(M) = M.
-C
-C        Compute the cos and sine that define  Phat.
-C
-         TEMP(1) = CSQ(1)*R(1,1) + SNQ*R(1,2)
-         TEMP(2) = CSQ(2)*R(1,1)
-         CALL SB03OV( TEMP, SNQ*R(2,2), CSP, SNP )
-C
-C        Compute p1, p2 and p3 of (6.11).
-C
-         P1 = TEMP(1)
-         TEMP(1) = CSQ(1)*R(1,2) - SNQ*R(1,1)
-         TEMP(2) = CSQ(2)*R(1,2)
-         TEMPR   = CSQ(1)*R(2,2)
-         TEMPI   = CSQ(2)*R(2,2)
-         P2(1)   = CSP(1)*TEMP(1) - CSP(2)*TEMP(2) + SNP*TEMPR
-         P2(2)   = CSP(1)*TEMP(2) + CSP(2)*TEMP(1) + SNP*TEMPI
-         P3R     = CSP(1)*TEMPR   + CSP(2)*TEMPI   - SNP*TEMP(1)
-         P3I     = CSP(2)*TEMPR   - CSP(1)*TEMPI   + SNP*TEMP(2)
-      END IF
-C
-C     Make  p3  real by multiplying by  conjg ( p3 )/abs( p3 )  to give
-C
-C     p3 := abs( p3 ).
-C
-      IF ( P3I.EQ.ZERO ) THEN
-         P3 = ABS( P3R )
-         DP(1) = SIGN( ONE, P3R )
-         DP(2) = ZERO
-      ELSE
-         P3 = DLAPY2( P3R, P3I )
-         DP(1) =  P3R/P3
-         DP(2) = -P3I/P3
-      END IF
-C
-C     Now compute the quantities v1, v2, v3 and y in (6.13) - (6.15),
-C     or (10.23) - (10.25). Care is taken to avoid overflows.
-C
-      IF ( DISCR ) THEN
-         ALPHA = SQRT( ABS( ONE - ABSB )*( ONE + ABSB ) )
-      ELSE
-         ALPHA = SQRT( ABS( TWO*E1 ) )
-      END IF
-C
-      SCALOC = ONE
-      IF( ALPHA.LT.SMIN ) THEN
-         ALPHA = SMIN
-         INFO = 1
-      END IF
-      ABST = ABS( P1 )
-      IF( ALPHA.LT.ONE .AND. ABST.GT.ONE ) THEN
-         IF( ABST.GT.BIGNUM*ALPHA )
-     $      SCALOC = ONE / ABST
-      END IF
-      IF( SCALOC.NE.ONE ) THEN
-         P1    = SCALOC*P1
-         P2(1) = SCALOC*P2(1)
-         P2(2) = SCALOC*P2(2)
-         P3    = SCALOC*P3
-         SCALE = SCALOC*SCALE
-      END IF
-      V1 = P1/ALPHA
-C
-      IF ( DISCR ) THEN
-         G(1) = ( ONE - E1 )*( ONE + E1 ) + E2**2
-         G(2) = -TWO*E1*E2
-         ABSG =  DLAPY2( G(1), G(2) )
-         SCALOC = ONE
-         IF( ABSG.LT.SMIN ) THEN
-            ABSG = SMIN
-            INFO = 1
-         END IF
-         TEMP(1) = SGN*ALPHA*P2(1) + V1*( E1*T(1) - E2*T(2) )
-         TEMP(2) = SGN*ALPHA*P2(2) + V1*( E1*T(2) + E2*T(1) )
-         ABST    = MAX( ABS( TEMP(1) ), ABS( TEMP(2) ) )
-         IF( ABSG.LT.ONE .AND. ABST.GT.ONE ) THEN
-            IF( ABST.GT.BIGNUM*ABSG )
-     $         SCALOC = ONE / ABST
-         END IF
-         IF( SCALOC.NE.ONE ) THEN
-            V1      = SCALOC*V1
-            TEMP(1) = SCALOC*TEMP(1)
-            TEMP(2) = SCALOC*TEMP(2)
-            P1      = SCALOC*P1
-            P2(1)   = SCALOC*P2(1)
-            P2(2)   = SCALOC*P2(2)
-            P3      = SCALOC*P3
-            SCALE   = SCALOC*SCALE
-         END IF
-         TEMP(1) = TEMP(1)/ABSG
-         TEMP(2) = TEMP(2)/ABSG
-C
-         SCALOC = ONE
-         V2(1)  = G(1)*TEMP(1) + G(2)*TEMP(2)
-         V2(2)  = G(1)*TEMP(2) - G(2)*TEMP(1)
-         ABST   = MAX( ABS( V2(1) ), ABS( V2(2) ) )
-         IF( ABSG.LT.ONE .AND. ABST.GT.ONE ) THEN
-            IF( ABST.GT.BIGNUM*ABSG )
-     $         SCALOC = ONE / ABST
-         END IF
-         IF( SCALOC.NE.ONE ) THEN
-            V1    = SCALOC*V1
-            V2(1) = SCALOC*V2(1)
-            V2(2) = SCALOC*V2(2)
-            P1    = SCALOC*P1
-            P2(1) = SCALOC*P2(1)
-            P2(2) = SCALOC*P2(2)
-            P3    = SCALOC*P3
-            SCALE = SCALOC*SCALE
-         END IF
-         V2(1) = V2(1)/ABSG
-         V2(2) = V2(2)/ABSG
-C
-         SCALOC  = ONE
-         TEMP(1) = P1*T(1) - TWO*E2*P2(2)
-         TEMP(2) = P1*T(2) + TWO*E2*P2(1)
-         ABST    = MAX( ABS( TEMP(1) ), ABS( TEMP(2) ) )
-         IF( ABSG.LT.ONE .AND. ABST.GT.ONE ) THEN
-            IF( ABST.GT.BIGNUM*ABSG )
-     $         SCALOC = ONE / ABST
-         END IF
-         IF( SCALOC.NE.ONE ) THEN
-            TEMP(1) = SCALOC*TEMP(1)
-            TEMP(2) = SCALOC*TEMP(2)
-            V1      = SCALOC*V1
-            V2(1)   = SCALOC*V2(1)
-            V2(2)   = SCALOC*V2(2)
-            P3      = SCALOC*P3
-            SCALE   = SCALOC*SCALE
-         END IF
-         TEMP(1) = TEMP(1)/ABSG
-         TEMP(2) = TEMP(2)/ABSG
-C
-         SCALOC  = ONE
-         Y(1)    = -( G(1)*TEMP(1) + G(2)*TEMP(2) )
-         Y(2)    = -( G(1)*TEMP(2) - G(2)*TEMP(1) )
-         ABST    = MAX( ABS( Y(1) ), ABS( Y(2) ) )
-         IF( ABSG.LT.ONE .AND. ABST.GT.ONE ) THEN
-            IF( ABST.GT.BIGNUM*ABSG )
-     $         SCALOC = ONE / ABST
-         END IF
-         IF( SCALOC.NE.ONE ) THEN
-            Y(1)  = SCALOC*Y(1)
-            Y(2)  = SCALOC*Y(2)
-            V1    = SCALOC*V1
-            V2(1) = SCALOC*V2(1)
-            V2(2) = SCALOC*V2(2)
-            P3    = SCALOC*P3
-            SCALE = SCALOC*SCALE
-         END IF
-         Y(1) = Y(1)/ABSG
-         Y(2) = Y(2)/ABSG
-      ELSE
-C
-         SCALOC = ONE
-         IF( ABSB.LT.SMIN ) THEN
-            ABSB = SMIN
-            INFO = 1
-         END IF
-         TEMP(1) = SGN*ALPHA*P2(1) + V1*T(1)
-         TEMP(2) = SGN*ALPHA*P2(2) + V1*T(2)
-         ABST    = MAX( ABS( TEMP(1) ), ABS( TEMP(2) ) )
-         IF( ABSB.LT.ONE .AND. ABST.GT.ONE ) THEN
-            IF( ABST.GT.BIGNUM*ABSB )
-     $         SCALOC = ONE / ABST
-         END IF
-         IF( SCALOC.NE.ONE ) THEN
-            V1      = SCALOC*V1
-            TEMP(1) = SCALOC*TEMP(1)
-            TEMP(2) = SCALOC*TEMP(2)
-            P2(1)   = SCALOC*P2(1)
-            P2(2)   = SCALOC*P2(2)
-            P3      = SCALOC*P3
-            SCALE   = SCALOC*SCALE
-         END IF
-         TEMP(1) = TEMP(1)/( TWO*ABSB )
-         TEMP(2) = TEMP(2)/( TWO*ABSB )
-         SCALOC  = ONE
-         V2(1)   = -( E1*TEMP(1) + E2*TEMP(2) )
-         V2(2)   = -( E1*TEMP(2) - E2*TEMP(1) )
-         ABST = MAX( ABS( V2(1) ), ABS( V2(2) ) )
-         IF( ABSB.LT.ONE .AND. ABST.GT.ONE ) THEN
-            IF( ABST.GT.BIGNUM*ABSB )
-     $         SCALOC = ONE / ABST
-         END IF
-         IF( SCALOC.NE.ONE ) THEN
-            V1    = SCALOC*V1
-            V2(1) = SCALOC*V2(1)
-            V2(2) = SCALOC*V2(2)
-            P2(1) = SCALOC*P2(1)
-            P2(2) = SCALOC*P2(2)
-            P3    = SCALOC*P3
-            SCALE = SCALOC*SCALE
-         END IF
-         V2(1) = V2(1)/ABSB
-         V2(2) = V2(2)/ABSB
-         Y(1)  = P2(1) - ALPHA*V2(1)
-         Y(2)  = P2(2) - ALPHA*V2(2)
-      END IF
-C
-      SCALOC = ONE
-      V3     = DLAPY3( P3, Y(1), Y(2) )
-      IF( ALPHA.LT.ONE .AND. V3.GT.ONE ) THEN
-         IF( V3.GT.BIGNUM*ALPHA )
-     $      SCALOC = ONE / V3
-      END IF
-      IF( SCALOC.NE.ONE ) THEN
-         V1    = SCALOC*V1
-         V2(1) = SCALOC*V2(1)
-         V2(2) = SCALOC*V2(2)
-         V3    = SCALOC*V3
-         P3    = SCALOC*P3
-         SCALE = SCALOC*SCALE
-      END IF
-      V3 = V3/ALPHA
-C
-      IF ( LTRANS ) THEN
-C
-C        Case op(M) = M'.
-C
-C        Form  X = conjg( Qhat' )*v11.
-C
-         X11(1) =  CSQ(1)*V3
-         X11(2) =  CSQ(2)*V3
-         X21(1) =  SNQ*V3
-         X12(1) =  CSQ(1)*V2(1) + CSQ(2)*V2(2) - SNQ*V1
-         X12(2) = -CSQ(1)*V2(2) + CSQ(2)*V2(1)
-         X22(1) =  CSQ(1)*V1 + SNQ*V2(1)
-         X22(2) = -CSQ(2)*V1 - SNQ*V2(2)
-C
-C        Obtain u11 from the RQ-factorization of X. The conjugate of
-C        X22 should be taken.
-C
-         X22(2) = -X22(2)
-         CALL SB03OV( X22, X21(1), CST, SNT )
-         R(2,2) = X22(1)
-         R(1,2) = CST(1)*X12(1) - CST(2)*X12(2) + SNT*X11(1)
-         TEMPR  = CST(1)*X11(1) + CST(2)*X11(2) - SNT*X12(1)
-         TEMPI  = CST(1)*X11(2) - CST(2)*X11(1) - SNT*X12(2)
-         IF ( TEMPI.EQ.ZERO ) THEN
-            R(1,1) = ABS( TEMPR )
-            DT(1)  = SIGN( ONE, TEMPR )
-            DT(2)  = ZERO
-         ELSE
-            R(1,1) =  DLAPY2( TEMPR, TEMPI )
-            DT(1)  =  TEMPR/R(1,1)
-            DT(2)  = -TEMPI/R(1,1)
-         END IF
-      ELSE
-C
-C        Case op(M) = M.
-C
-C        Now form  X = v11*conjg( Qhat' ).
-C
-         X11(1) =  CSQ(1)*V1 - SNQ*V2(1)
-         X11(2) = -CSQ(2)*V1 + SNQ*V2(2)
-         X21(1) = -SNQ*V3
-         X12(1) =  CSQ(1)*V2(1) + CSQ(2)*V2(2) + SNQ*V1
-         X12(2) = -CSQ(1)*V2(2) + CSQ(2)*V2(1)
-         X22(1) =  CSQ(1)*V3
-         X22(2) =  CSQ(2)*V3
-C
-C        Obtain u11 from the QR-factorization of X.
-C
-         CALL SB03OV( X11, X21(1), CST, SNT )
-         R(1,1) = X11(1)
-         R(1,2) = CST(1)*X12(1) + CST(2)*X12(2) + SNT*X22(1)
-         TEMPR  = CST(1)*X22(1) - CST(2)*X22(2) - SNT*X12(1)
-         TEMPI  = CST(1)*X22(2) + CST(2)*X22(1) - SNT*X12(2)
-         IF ( TEMPI.EQ.ZERO ) THEN
-            R(2,2) = ABS( TEMPR )
-            DT(1)  = SIGN( ONE, TEMPR )
-            DT(2)  = ZERO
-         ELSE
-            R(2,2) =  DLAPY2( TEMPR, TEMPI )
-            DT(1)  =  TEMPR/R(2,2)
-            DT(2)  = -TEMPI/R(2,2)
-         END IF
-      END IF
-C
-C     The computations below are not needed when B and A are not
-C     useful. Compute delta, eta and gamma as in (6.21) or (10.26).
-C
-      IF ( ( Y(1).EQ.ZERO ).AND.( Y(2).EQ.ZERO ) ) THEN
-         DELTA(1) = ZERO
-         DELTA(2) = ZERO
-         GAMMA(1) = ZERO
-         GAMMA(2) = ZERO
-         ETA = ALPHA
-      ELSE
-         DELTA(1) =  Y(1)/V3
-         DELTA(2) =  Y(2)/V3
-         GAMMA(1) = -ALPHA*DELTA(1)
-         GAMMA(2) = -ALPHA*DELTA(2)
-         ETA = P3/V3
-         IF ( DISCR ) THEN
-            TEMPR    = E1*DELTA(1) - E2*DELTA(2)
-            DELTA(2) = E1*DELTA(2) + E2*DELTA(1)
-            DELTA(1) = TEMPR
-         END IF
-      END IF
-C
-      IF ( LTRANS ) THEN
-C
-C        Case op(M) = M'.
-C
-C        Find  X = conjg( That' )*( inv( v11 )*s11hat*v11 ).
-C        ( Defer the scaling.)
-C
-         X11(1) =  CST(1)*E1 + CST(2)*E2
-         X11(2) = -CST(1)*E2 + CST(2)*E1
-         X21(1) =  SNT*E1
-         X21(2) = -SNT*E2
-         X12(1) =  SGN*(  CST(1)*GAMMA(1) + CST(2)*GAMMA(2) ) - SNT*E1
-         X12(2) =  SGN*( -CST(1)*GAMMA(2) + CST(2)*GAMMA(1) ) - SNT*E2
-         X22(1) =  CST(1)*E1 + CST(2)*E2 + SGN*SNT*GAMMA(1)
-         X22(2) =  CST(1)*E2 - CST(2)*E1 - SGN*SNT*GAMMA(2)
-C
-C        Now find  B = X*That. ( Include the scaling here.)
-C
-         S(1,1) = CST(1)*X11(1) + CST(2)*X11(2) - SNT*X12(1)
-         TEMPR  = CST(1)*X21(1) + CST(2)*X21(2) - SNT*X22(1)
-         TEMPI  = CST(1)*X21(2) - CST(2)*X21(1) - SNT*X22(2)
-         S(2,1) = DT(1)*TEMPR   - DT(2)*TEMPI
-         TEMPR  = CST(1)*X12(1) - CST(2)*X12(2) + SNT*X11(1)
-         TEMPI  = CST(1)*X12(2) + CST(2)*X12(1) + SNT*X11(2)
-         S(1,2) = DT(1)*TEMPR   + DT(2)*TEMPI
-         S(2,2) = CST(1)*X22(1) - CST(2)*X22(2) + SNT*X21(1)
-C
-C        Form  X = ( inv( v11 )*p11 )*conjg( Phat' ).
-C
-         TEMPR  =  DP(1)*ETA
-         TEMPI  = -DP(2)*ETA
-         X11(1) =  CSP(1)*TEMPR - CSP(2)*TEMPI + SNP*DELTA(1)
-         X11(2) =  CSP(1)*TEMPI + CSP(2)*TEMPR - SNP*DELTA(2)
-         X21(1) =  SNP*ALPHA
-         X12(1) = -SNP*TEMPR + CSP(1)*DELTA(1) - CSP(2)*DELTA(2)
-         X12(2) = -SNP*TEMPI - CSP(1)*DELTA(2) - CSP(2)*DELTA(1)
-         X22(1) =  CSP(1)*ALPHA
-         X22(2) = -CSP(2)*ALPHA
-C
-C        Finally form  A = conjg( That' )*X.
-C
-         TEMPR  = CST(1)*X11(1) - CST(2)*X11(2) - SNT*X21(1)
-         TEMPI  = CST(1)*X22(2) + CST(2)*X22(1)
-         A(1,1) = DT(1)*TEMPR   + DT(2)*TEMPI
-         TEMPR  = CST(1)*X12(1) - CST(2)*X12(2) - SNT*X22(1)
-         TEMPI  = CST(1)*X12(2) + CST(2)*X12(1) - SNT*X22(1)
-         A(1,2) = DT(1)*TEMPR   + DT(2)*TEMPI
-         A(2,1) = ZERO
-         A(2,2) = CST(1)*X22(1) + CST(2)*X22(2) + SNT*X12(1)
-      ELSE
-C
-C        Case op(M) = M.
-C
-C        Find  X = That*( v11*s11hat*inv( v11 ) ). ( Defer the scaling.)
-C
-         X11(1) =  CST(1)*E1 + CST(2)*E2
-         X11(2) =  CST(1)*E2 - CST(2)*E1
-         X21(1) = -SNT*E1
-         X21(2) = -SNT*E2
-         X12(1) =  SGN*(  CST(1)*GAMMA(1) - CST(2)*GAMMA(2) ) + SNT*E1
-         X12(2) =  SGN*( -CST(1)*GAMMA(2) - CST(2)*GAMMA(1) ) - SNT*E2
-         X22(1) =  CST(1)*E1 + CST(2)*E2 - SGN*SNT*GAMMA(1)
-         X22(2) = -CST(1)*E2 + CST(2)*E1 + SGN*SNT*GAMMA(2)
-C
-C        Now find  B = X*conjg( That' ). ( Include the scaling here.)
-C
-         S(1,1) = CST(1)*X11(1) - CST(2)*X11(2) + SNT*X12(1)
-         TEMPR  = CST(1)*X21(1) - CST(2)*X21(2) + SNT*X22(1)
-         TEMPI  = CST(1)*X21(2) + CST(2)*X21(1) + SNT*X22(2)
-         S(2,1) = DT(1)*TEMPR   - DT(2)*TEMPI
-         TEMPR  = CST(1)*X12(1) + CST(2)*X12(2) - SNT*X11(1)
-         TEMPI  = CST(1)*X12(2) - CST(2)*X12(1) - SNT*X11(2)
-         S(1,2) = DT(1)*TEMPR   + DT(2)*TEMPI
-         S(2,2) = CST(1)*X22(1) + CST(2)*X22(2) - SNT*X21(1)
-C
-C        Form  X = Phat*( p11*inv( v11 ) ).
-C
-         TEMPR  =  DP(1)*ETA
-         TEMPI  = -DP(2)*ETA
-         X11(1) =  CSP(1)*ALPHA
-         X11(2) =  CSP(2)*ALPHA
-         X21(1) =  SNP*ALPHA
-         X12(1) =  CSP(1)*DELTA(1) + CSP(2)*DELTA(2) - SNP*TEMPR
-         X12(2) = -CSP(1)*DELTA(2) + CSP(2)*DELTA(1) - SNP*TEMPI
-         X22(1) =  CSP(1)*TEMPR + CSP(2)*TEMPI + SNP*DELTA(1)
-         X22(2) =  CSP(1)*TEMPI - CSP(2)*TEMPR - SNP*DELTA(2)
-C
-C        Finally form  A = X*conjg( That' ).
-C
-         A(1,1) = CST(1)*X11(1) - CST(2)*X11(2) + SNT*X12(1)
-         A(2,1) = ZERO
-         A(1,2) = CST(1)*X12(1) + CST(2)*X12(2) - SNT*X11(1)
-         TEMPR  = CST(1)*X22(1) + CST(2)*X22(2) - SNT*X21(1)
-         TEMPI  = CST(1)*X22(2) - CST(2)*X22(1)
-         A(2,2) = DT(1)*TEMPR   + DT(2)*TEMPI
-      END IF
-C
-      IF( SCALE.NE.ONE ) THEN
-         A(1,1) = SCALE*A(1,1)
-         A(1,2) = SCALE*A(1,2)
-         A(2,2) = SCALE*A(2,2)
-      END IF
-C
-      RETURN
-C *** Last line of SB03OY ***
-      END
--- a/extra/control-devel/src/SB03QX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,394 +0,0 @@
-      SUBROUTINE SB03QX( TRANA, UPLO, LYAPUN, N, XANORM, T, LDT, U, LDU,
-     $                   R, LDR, FERR, 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 estimate a forward error bound for the solution X of a real
-C     continuous-time Lyapunov matrix equation,
-C
-C            op(A)'*X + X*op(A) = C,
-C
-C     where op(A) = A or A' (A**T) and C is symmetric (C = C**T). The
-C     matrix A, the right hand side C, and the solution X are N-by-N.
-C     An absolute residual matrix, which takes into account the rounding
-C     errors in forming it, is given in the array R.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     UPLO    CHARACTER*1
-C             Specifies which part of the symmetric matrix R is to be
-C             used, as follows:
-C             = 'U':  Upper triangular part;
-C             = 'L':  Lower triangular part.
-C
-C     LYAPUN  CHARACTER*1
-C             Specifies whether or not the original Lyapunov equations
-C             should be solved, as follows:
-C             = 'O':  Solve the original Lyapunov equations, updating
-C                     the right-hand sides and solutions with the
-C                     matrix U, e.g., X <-- U'*X*U;
-C             = 'R':  Solve reduced Lyapunov equations only, without
-C                     updating the right-hand sides and solutions.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A and R.  N >= 0.
-C
-C     XANORM  (input) DOUBLE PRECISION
-C             The absolute (maximal) norm of the symmetric solution
-C             matrix X of the Lyapunov equation.  XANORM >= 0.
-C
-C     T       (input) DOUBLE PRECISION array, dimension (LDT,N)
-C             The leading N-by-N upper Hessenberg part of this array
-C             must contain the upper quasi-triangular matrix T in Schur
-C             canonical form from a Schur factorization of A.
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.  LDT >= MAX(1,N).
-C
-C     U       (input) DOUBLE PRECISION array, dimension (LDU,N)
-C             The leading N-by-N part of this array must contain the
-C             orthogonal matrix U from a real Schur factorization of A.
-C             If LYAPUN = 'R', the array U is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of array U.
-C             LDU >= 1,        if LYAPUN = 'R';
-C             LDU >= MAX(1,N), if LYAPUN = 'O'.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,N)
-C             On entry, if UPLO = 'U', the leading N-by-N upper
-C             triangular part of this array must contain the upper
-C             triangular part of the absolute residual matrix R, with
-C             bounds on rounding errors added.
-C             On entry, if UPLO = 'L', the leading N-by-N lower
-C             triangular part of this array must contain the lower
-C             triangular part of the absolute residual matrix R, with
-C             bounds on rounding errors added.
-C             On exit, the leading N-by-N part of this array contains
-C             the symmetric absolute residual matrix R (with bounds on
-C             rounding errors added), fully stored.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,N).
-C
-C     FERR    (output) DOUBLE PRECISION
-C             An estimated forward error bound for the solution X.
-C             If XTRUE is the true solution, FERR bounds the magnitude
-C             of the largest entry in (X - XTRUE) divided by the
-C             magnitude of the largest entry in X.
-C             If N = 0 or XANORM = 0, FERR is set to 0, without any
-C             calculations.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N*N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.  LDWORK >= 2*N*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             = N+1:  if the matrices T and -T' have common or very
-C                   close eigenvalues; perturbed values were used to
-C                   solve Lyapunov equations (but the matrix T is
-C                   unchanged).
-C
-C     METHOD
-C
-C     The forward error bound is estimated using a practical error bound
-C     similar to the one proposed in [1], based on the 1-norm estimator
-C     in [2].
-C
-C     REFERENCES
-C
-C     [1] Higham, N.J.
-C         Perturbation theory and backward error for AX-XB=C.
-C         BIT, vol. 33, pp. 124-136, 1993.
-C
-C     [2] Higham, N.J.
-C         FORTRAN codes for estimating the one-norm of a real or
-C         complex matrix, with applications to condition estimation.
-C         ACM Trans. Math. Softw., 14, pp. 381-396, 1988.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations.
-C
-C     FURTHER COMMENTS
-C
-C     The option LYAPUN = 'R' may occasionally produce slightly worse
-C     or better estimates, and it is much faster than the option 'O'.
-C     The routine can be also used as a final step in estimating a
-C     forward error bound for the solution of a continuous-time
-C     algebraic matrix Riccati equation.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Romania,
-C     Oct. 1998. Partly based on DGLSVX (and then SB03QD) by P. Petkov,
-C     Tech. University of Sofia, March 1998 (and December 1998).
-C
-C     REVISIONS
-C
-C     February 6, 1999, V. Sima, Katholieke Univ. Leuven, Belgium.
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2004.
-C
-C     KEYWORDS
-C
-C     Lyapunov equation, orthogonal transformation, real Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, HALF
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, HALF = 0.5D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          LYAPUN, TRANA, UPLO
-      INTEGER            INFO, LDR, LDT, LDU, LDWORK, N
-      DOUBLE PRECISION   FERR, XANORM
-C     ..
-C     .. Array Arguments ..
-      INTEGER            IWORK( * )
-      DOUBLE PRECISION   DWORK( * ), R( LDR, * ), T( LDT, * ),
-     $                   U( LDU, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            LOWER, NOTRNA, UPDATE
-      CHARACTER          TRANAT, UPLOW
-      INTEGER            I, IJ, INFO2, ITMP, J, KASE, NN
-      DOUBLE PRECISION   EST, SCALE, TEMP
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DLANSY
-      EXTERNAL           DLANSY, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DLACON, DSCAL, MA02ED, MB01RU, SB03MY, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode and Test input parameters.
-C
-      NOTRNA = LSAME( TRANA,  'N' )
-      UPDATE = LSAME( LYAPUN, 'O' )
-C
-      NN   = N*N
-      INFO = 0
-      IF( .NOT.( NOTRNA .OR. LSAME( TRANA, 'T' ) .OR.
-     $                       LSAME( TRANA, 'C' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( LSAME( UPLO, 'L' ) .OR. LSAME( UPLO, 'U' ) ) )
-     $   THEN
-         INFO = -2
-      ELSE IF( .NOT.( UPDATE .OR. LSAME( LYAPUN, 'R' ) ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( XANORM.LT.ZERO ) THEN
-         INFO = -5
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( LDU.LT.1 .OR. ( UPDATE .AND. LDU.LT.N ) ) THEN
-         INFO = -9
-      ELSE IF( LDR.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDWORK.LT.2*NN ) THEN
-         INFO = -15
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'SB03QX', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      FERR = ZERO
-      IF( N.EQ.0 .OR. XANORM.EQ.ZERO )
-     $   RETURN
-C
-      ITMP = NN + 1
-C
-      IF( NOTRNA ) THEN
-         TRANAT = 'T'
-      ELSE
-         TRANAT = 'N'
-      END IF
-C
-C     Fill in the remaining triangle of the symmetric residual matrix.
-C
-      CALL MA02ED( UPLO, N, R, LDR )
-C
-      KASE = 0
-C
-C     REPEAT
-   10 CONTINUE
-      CALL DLACON( NN, DWORK( ITMP ), DWORK, IWORK, EST, KASE )
-      IF( KASE.NE.0 ) THEN
-C
-C        Select the triangular part of symmetric matrix to be used.
-C
-         IF( DLANSY( '1-norm', 'Upper', N, DWORK, N, DWORK( ITMP ) )
-     $       .GE.
-     $       DLANSY( '1-norm', 'Lower', N, DWORK, N, DWORK( ITMP ) )
-     $     ) THEN
-            UPLOW = 'U'
-            LOWER = .FALSE.
-         ELSE
-            UPLOW = 'L'
-            LOWER = .TRUE.
-         END IF
-C
-         IF( KASE.EQ.2 ) THEN
-            IJ = 0
-            IF( LOWER ) THEN
-C
-C              Scale the lower triangular part of symmetric matrix
-C              by the residual matrix.
-C
-               DO 30 J = 1, N
-                  DO 20 I = J, N
-                     IJ = IJ + 1
-                     DWORK( IJ ) = DWORK( IJ )*R( I, J )
-   20             CONTINUE
-                  IJ = IJ + J
-   30          CONTINUE
-            ELSE
-C
-C              Scale the upper triangular part of symmetric matrix
-C              by the residual matrix.
-C
-               DO 50 J = 1, N
-                  DO 40 I = 1, J
-                     IJ = IJ + 1
-                     DWORK( IJ ) = DWORK( IJ )*R( I, J )
-   40             CONTINUE
-                  IJ = IJ + N - J
-   50          CONTINUE
-            END IF
-         END IF
-C
-         IF( UPDATE ) THEN
-C
-C           Transform the right-hand side: RHS := U'*RHS*U.
-C
-            CALL MB01RU( UPLOW, 'Transpose', N, N, ZERO, ONE, DWORK, N,
-     $                   U, LDU, DWORK, N, DWORK( ITMP ), NN, INFO2 )
-            CALL DSCAL( N, HALF, DWORK, N+1 )
-         END IF
-         CALL MA02ED( UPLOW, N, DWORK, N )
-C
-         IF( KASE.EQ.2 ) THEN
-C
-C           Solve op(T)'*Y + Y*op(T) = scale*RHS.
-C
-            CALL SB03MY( TRANA, N, T, LDT, DWORK, N, SCALE, INFO2 )
-         ELSE
-C
-C           Solve op(T)*W + W*op(T)' = scale*RHS.
-C
-            CALL SB03MY( TRANAT, N, T, LDT, DWORK, N, SCALE, INFO2 )
-         END IF
-C
-         IF( INFO2.GT.0 )
-     $      INFO = N + 1
-C
-         IF( UPDATE ) THEN
-C
-C           Transform back to obtain the solution: Z := U*Z*U', with
-C           Z = Y or Z = W.
-C
-            CALL MB01RU( UPLOW, 'No transpose', N, N, ZERO, ONE, DWORK,
-     $                   N, U, LDU, DWORK, N, DWORK( ITMP ), NN, INFO2 )
-            CALL DSCAL( N, HALF, DWORK, N+1 )
-         END IF
-C
-         IF( KASE.EQ.1 ) THEN
-            IJ = 0
-            IF( LOWER ) THEN
-C
-C              Scale the lower triangular part of symmetric matrix
-C              by the residual matrix.
-C
-               DO 70 J = 1, N
-                  DO 60 I = J, N
-                     IJ = IJ + 1
-                     DWORK( IJ ) = DWORK( IJ )*R( I, J )
-   60             CONTINUE
-                  IJ = IJ + J
-   70          CONTINUE
-            ELSE
-C
-C              Scale the upper triangular part of symmetric matrix
-C              by the residual matrix.
-C
-               DO 90 J = 1, N
-                  DO 80 I = 1, J
-                     IJ = IJ + 1
-                     DWORK( IJ ) = DWORK( IJ )*R( I, J )
-   80             CONTINUE
-                  IJ = IJ + N - J
-   90          CONTINUE
-            END IF
-         END IF
-C
-C        Fill in the remaining triangle of the symmetric matrix.
-C
-         CALL MA02ED( UPLOW, N, DWORK, N )
-         GO TO 10
-      END IF
-C
-C     UNTIL KASE = 0
-C
-C     Compute the estimate of the relative error.
-C
-      TEMP = XANORM*SCALE
-      IF( TEMP.GT.EST ) THEN
-         FERR = EST / TEMP
-      ELSE
-         FERR = ONE
-      END IF
-C
-      RETURN
-C
-C *** Last line of SB03QX ***
-      END
--- a/extra/control-devel/src/SB03QY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,443 +0,0 @@
-      SUBROUTINE SB03QY( JOB, TRANA, LYAPUN, N, T, LDT, U, LDU, X, LDX,
-     $                   SEP, THNORM, 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 estimate the separation between the matrices op(A) and -op(A)',
-C
-C     sep(op(A),-op(A)') = min norm(op(A)'*X + X*op(A))/norm(X)
-C                        = 1 / norm(inv(Omega))
-C
-C     and/or the 1-norm of Theta, where op(A) = A or A' (A**T), and
-C     Omega and Theta are linear operators associated to the real
-C     continuous-time Lyapunov matrix equation
-C
-C            op(A)'*X + X*op(A) = C,
-C
-C     defined by
-C
-C     Omega(W) = op(A)'*W + W*op(A),
-C     Theta(W) = inv(Omega(op(W)'*X + X*op(W))).
-C
-C     The 1-norm condition estimators are used.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies the computation to be performed, as follows:
-C             = 'S':  Compute the separation only;
-C             = 'T':  Compute the norm of Theta only;
-C             = 'B':  Compute both the separation and the norm of Theta.
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     LYAPUN  CHARACTER*1
-C             Specifies whether or not the original Lyapunov equations
-C             should be solved, as follows:
-C             = 'O':  Solve the original Lyapunov equations, updating
-C                     the right-hand sides and solutions with the
-C                     matrix U, e.g., X <-- U'*X*U;
-C             = 'R':  Solve reduced Lyapunov equations only, without
-C                     updating the right-hand sides and solutions.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A and X.  N >= 0.
-C
-C     T       (input) DOUBLE PRECISION array, dimension (LDT,N)
-C             The leading N-by-N upper Hessenberg part of this array
-C             must contain the upper quasi-triangular matrix T in Schur
-C             canonical form from a Schur factorization of A.
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.  LDT >= MAX(1,N).
-C
-C     U       (input) DOUBLE PRECISION array, dimension (LDU,N)
-C             The leading N-by-N part of this array must contain the
-C             orthogonal matrix U from a real Schur factorization of A.
-C             If LYAPUN = 'R', the array U is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of array U.
-C             LDU >= 1,        if LYAPUN = 'R';
-C             LDU >= MAX(1,N), if LYAPUN = 'O'.
-C
-C     X       (input) DOUBLE PRECISION array, dimension (LDX,N)
-C             The leading N-by-N part of this array must contain the
-C             solution matrix X of the Lyapunov equation (reduced
-C             Lyapunov equation if LYAPUN = 'R').
-C             If JOB = 'S', the array X is not referenced.
-C
-C     LDX     INTEGER
-C             The leading dimension of array X.
-C             LDX >= 1,        if JOB = 'S';
-C             LDX >= MAX(1,N), if JOB = 'T' or 'B'.
-C
-C     SEP     (output) DOUBLE PRECISION
-C             If JOB = 'S' or JOB = 'B', and INFO >= 0, SEP contains the
-C             estimated separation of the matrices op(A) and -op(A)'.
-C             If JOB = 'T' or N = 0, SEP is not referenced.
-C
-C     THNORM  (output) DOUBLE PRECISION
-C             If JOB = 'T' or JOB = 'B', and INFO >= 0, THNORM contains
-C             the estimated 1-norm of operator Theta.
-C             If JOB = 'S' or N = 0, THNORM is not referenced.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N*N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.  LDWORK >= 2*N*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             = N+1:  if the matrices T and -T' have common or very
-C                   close eigenvalues; perturbed values were used to
-C                   solve Lyapunov equations (but the matrix T is
-C                   unchanged).
-C
-C     METHOD
-C
-C     SEP is defined as the separation of op(A) and -op(A)':
-C
-C            sep( op(A), -op(A)' ) = sigma_min( K )
-C
-C     where sigma_min(K) is the smallest singular value of the
-C     N*N-by-N*N matrix
-C
-C        K = kprod( I(N), op(A)' ) + kprod( op(A)', I(N) ).
-C
-C     I(N) is an N-by-N identity matrix, and kprod denotes the Kronecker
-C     product. The routine estimates sigma_min(K) by the reciprocal of
-C     an estimate of the 1-norm of inverse(K), computed as suggested in
-C     [1]. This involves the solution of several continuous-time
-C     Lyapunov equations, either direct or transposed. The true
-C     reciprocal 1-norm of inverse(K) cannot differ from sigma_min(K) by
-C     more than a factor of N.
-C     The 1-norm of Theta is estimated similarly.
-C
-C     REFERENCES
-C
-C     [1] Higham, N.J.
-C         FORTRAN codes for estimating the one-norm of a real or
-C         complex matrix, with applications to condition estimation.
-C         ACM Trans. Math. Softw., 14, pp. 381-396, 1988.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations.
-C
-C     FURTHER COMMENTS
-C
-C     When SEP is zero, the routine returns immediately, with THNORM
-C     (if requested) not set. In this case, the equation is singular.
-C     The option LYAPUN = 'R' may occasionally produce slightly worse
-C     or better estimates, and it is much faster than the option 'O'.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Romania,
-C     Oct. 1998. Partly based on DGLSVX (and then SB03QD) by P. Petkov,
-C     Tech. University of Sofia, March 1998 (and December 1998).
-C
-C     REVISIONS
-C
-C     February 13, 1999, V. Sima, Katholieke Univ. Leuven, Belgium.
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2004.
-C
-C     KEYWORDS
-C
-C     Lyapunov equation, orthogonal transformation, real Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, HALF
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, HALF = 0.5D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          JOB, LYAPUN, TRANA
-      INTEGER            INFO, LDT, LDU, LDWORK, LDX, N
-      DOUBLE PRECISION   SEP, THNORM
-C     ..
-C     .. Array Arguments ..
-      INTEGER            IWORK( * )
-      DOUBLE PRECISION   DWORK( * ), T( LDT, * ), U( LDU, * ),
-     $                   X( LDX, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            NOTRNA, UPDATE, WANTS, WANTT
-      CHARACTER          TRANAT, UPLO
-      INTEGER            INFO2, ITMP, KASE, NN
-      DOUBLE PRECISION   BIGNUM, EST, SCALE
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DLAMCH, DLANSY
-      EXTERNAL           DLAMCH, DLANSY, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DLACON, DLACPY, DSCAL, DSYR2K, MA02ED, MB01RU,
-     $                   SB03MY, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode and Test input parameters.
-C
-      WANTS  = LSAME( JOB,    'S' )
-      WANTT  = LSAME( JOB,    'T' )
-      NOTRNA = LSAME( TRANA,  'N' )
-      UPDATE = LSAME( LYAPUN, 'O' )
-C
-      NN   = N*N
-      INFO = 0
-      IF( .NOT. ( WANTS .OR. WANTT .OR. LSAME( JOB, 'B' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( NOTRNA .OR. LSAME( TRANA, 'T' ) .OR.
-     $                            LSAME( TRANA, 'C' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.( UPDATE .OR. LSAME( LYAPUN, 'R' ) ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDU.LT.1 .OR. ( UPDATE .AND. LDU.LT.N ) ) THEN
-         INFO = -8
-      ELSE IF( LDX.LT.1 .OR. ( .NOT.WANTS .AND. LDX.LT.N ) ) THEN
-         INFO = -10
-      ELSE IF( LDWORK.LT.2*NN ) THEN
-         INFO = -15
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'SB03QY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( N.EQ.0 )
-     $   RETURN
-C
-      ITMP = NN + 1
-C
-      IF( NOTRNA ) THEN
-         TRANAT = 'T'
-      ELSE
-         TRANAT = 'N'
-      END IF
-C
-      IF( .NOT.WANTT ) THEN
-C
-C        Estimate sep(op(A),-op(A)').
-C        Workspace:  2*N*N.
-C
-         KASE = 0
-C
-C        REPEAT
-   10    CONTINUE
-         CALL DLACON( NN, DWORK( ITMP ), DWORK, IWORK, EST, KASE )
-         IF( KASE.NE.0 ) THEN
-C
-C           Select the triangular part of symmetric matrix to be used.
-C
-            IF( DLANSY( '1-norm', 'Upper', N, DWORK, N, DWORK( ITMP ) )
-     $          .GE.
-     $          DLANSY( '1-norm', 'Lower', N, DWORK, N, DWORK( ITMP ) )
-     $        ) THEN
-               UPLO = 'U'
-            ELSE
-               UPLO = 'L'
-            END IF
-C
-            IF( UPDATE ) THEN
-C
-C              Transform the right-hand side: RHS := U'*RHS*U.
-C
-               CALL MB01RU( UPLO, 'Transpose', N, N, ZERO, ONE, DWORK,
-     $                      N, U, LDU, DWORK, N, DWORK( ITMP ), NN,
-     $                      INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-            END IF
-            CALL MA02ED( UPLO, N, DWORK, N )
-C
-            IF( KASE.EQ.1 ) THEN
-C
-C              Solve op(T)'*Y + Y*op(T) = scale*RHS.
-C
-               CALL SB03MY( TRANA, N, T, LDT, DWORK, N, SCALE, INFO2 )
-            ELSE
-C
-C              Solve op(T)*W + W*op(T)' = scale*RHS.
-C
-               CALL SB03MY( TRANAT, N, T, LDT, DWORK, N, SCALE, INFO2 )
-            END IF
-C
-            IF( INFO2.GT.0 )
-     $         INFO = N + 1
-C
-            IF( UPDATE ) THEN
-C
-C              Transform back to obtain the solution: Z := U*Z*U', with
-C              Z = Y or Z = W.
-C
-               CALL MB01RU( UPLO, 'No transpose', N, N, ZERO, ONE,
-     $                      DWORK, N, U, LDU, DWORK, N, DWORK( ITMP ),
-     $                      NN, INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-C
-C              Fill in the remaining triangle of the symmetric matrix.
-C
-               CALL MA02ED( UPLO, N, DWORK, N )
-            END IF
-C
-            GO TO 10
-         END IF
-C        UNTIL KASE = 0
-C
-         IF( EST.GT.SCALE ) THEN
-            SEP = SCALE / EST
-         ELSE
-            BIGNUM = ONE / DLAMCH( 'Safe minimum' )
-            IF( SCALE.LT.EST*BIGNUM ) THEN
-               SEP = SCALE / EST
-            ELSE
-               SEP = BIGNUM
-            END IF
-         END IF
-C
-C        Return if the equation is singular.
-C
-         IF( SEP.EQ.ZERO )
-     $      RETURN
-      END IF
-C
-      IF( .NOT.WANTS ) THEN
-C
-C        Estimate norm(Theta).
-C        Workspace:  2*N*N.
-C
-         KASE = 0
-C
-C        REPEAT
-   20    CONTINUE
-         CALL DLACON( NN, DWORK( ITMP ), DWORK, IWORK, EST, KASE )
-         IF( KASE.NE.0 ) THEN
-C
-C           Select the triangular part of symmetric matrix to be used.
-C
-            IF( DLANSY( '1-norm', 'Upper', N, DWORK, N, DWORK( ITMP ) )
-     $          .GE.
-     $          DLANSY( '1-norm', 'Lower', N, DWORK, N, DWORK( ITMP ) )
-     $        ) THEN
-               UPLO = 'U'
-            ELSE
-               UPLO = 'L'
-            END IF
-C
-C           Fill in the remaining triangle of the symmetric matrix.
-C
-            CALL MA02ED( UPLO, N, DWORK, N )
-C
-C           Compute RHS = op(W)'*X + X*op(W).
-C
-            CALL DSYR2K( UPLO, TRANAT, N, N, ONE, DWORK, N, X, LDX,
-     $                   ZERO, DWORK( ITMP ), N )
-            CALL DLACPY( UPLO, N, N, DWORK( ITMP ), N, DWORK, N )
-C
-            IF( UPDATE ) THEN
-C
-C              Transform the right-hand side: RHS := U'*RHS*U.
-C
-               CALL MB01RU( UPLO, 'Transpose', N, N, ZERO, ONE, DWORK,
-     $                      N, U, LDU, DWORK, N, DWORK( ITMP ), NN,
-     $                      INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-            END IF
-            CALL MA02ED( UPLO, N, DWORK, N )
-C
-            IF( KASE.EQ.1 ) THEN
-C
-C              Solve op(T)'*Y + Y*op(T) = scale*RHS.
-C
-               CALL SB03MY( TRANA, N, T, LDT, DWORK, N, SCALE, INFO2 )
-            ELSE
-C
-C              Solve op(T)*W + W*op(T)' = scale*RHS.
-C
-               CALL SB03MY( TRANAT, N, T, LDT, DWORK, N, SCALE, INFO2 )
-            END IF
-C
-            IF( INFO2.GT.0 )
-     $         INFO = N + 1
-C
-            IF( UPDATE ) THEN
-C
-C              Transform back to obtain the solution: Z := U*Z*U', with
-C              Z = Y or Z = W.
-C
-               CALL MB01RU( UPLO, 'No transpose', N, N, ZERO, ONE,
-     $                      DWORK, N, U, LDU, DWORK, N, DWORK( ITMP ),
-     $                      NN, INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-C
-C              Fill in the remaining triangle of the symmetric matrix.
-C
-               CALL MA02ED( UPLO, N, DWORK, N )
-            END IF
-C
-            GO TO 20
-         END IF
-C        UNTIL KASE = 0
-C
-         IF( EST.LT.SCALE ) THEN
-            THNORM = EST / SCALE
-         ELSE
-            BIGNUM = ONE / DLAMCH( 'Safe minimum' )
-            IF( EST.LT.SCALE*BIGNUM ) THEN
-               THNORM = EST / SCALE
-            ELSE
-               THNORM = BIGNUM
-            END IF
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of SB03QY ***
-      END
--- a/extra/control-devel/src/SB03SX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,398 +0,0 @@
-      SUBROUTINE SB03SX( TRANA, UPLO, LYAPUN, N, XANORM, T, LDT, U, LDU,
-     $                   R, LDR, FERR, 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 estimate a forward error bound for the solution X of a real
-C     discrete-time Lyapunov matrix equation,
-C
-C            op(A)'*X*op(A) - X = C,
-C
-C     where op(A) = A or A' (A**T) and C is symmetric (C = C**T). The
-C     matrix A, the right hand side C, and the solution X are N-by-N.
-C     An absolute residual matrix, which takes into account the rounding
-C     errors in forming it, is given in the array R.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     UPLO    CHARACTER*1
-C             Specifies which part of the symmetric matrix R is to be
-C             used, as follows:
-C             = 'U':  Upper triangular part;
-C             = 'L':  Lower triangular part.
-C
-C     LYAPUN  CHARACTER*1
-C             Specifies whether or not the original Lyapunov equations
-C             should be solved, as follows:
-C             = 'O':  Solve the original Lyapunov equations, updating
-C                     the right-hand sides and solutions with the
-C                     matrix U, e.g., X <-- U'*X*U;
-C             = 'R':  Solve reduced Lyapunov equations only, without
-C                     updating the right-hand sides and solutions.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A and R.  N >= 0.
-C
-C     XANORM  (input) DOUBLE PRECISION
-C             The absolute (maximal) norm of the symmetric solution
-C             matrix X of the Lyapunov equation.  XANORM >= 0.
-C
-C     T       (input) DOUBLE PRECISION array, dimension (LDT,N)
-C             The leading N-by-N upper Hessenberg part of this array
-C             must contain the upper quasi-triangular matrix T in Schur
-C             canonical form from a Schur factorization of A.
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.  LDT >= MAX(1,N).
-C
-C     U       (input) DOUBLE PRECISION array, dimension (LDU,N)
-C             The leading N-by-N part of this array must contain the
-C             orthogonal matrix U from a real Schur factorization of A.
-C             If LYAPUN = 'R', the array U is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of array U.
-C             LDU >= 1,        if LYAPUN = 'R';
-C             LDU >= MAX(1,N), if LYAPUN = 'O'.
-C
-C     R       (input/output) DOUBLE PRECISION array, dimension (LDR,N)
-C             On entry, if UPLO = 'U', the leading N-by-N upper
-C             triangular part of this array must contain the upper
-C             triangular part of the absolute residual matrix R, with
-C             bounds on rounding errors added.
-C             On entry, if UPLO = 'L', the leading N-by-N lower
-C             triangular part of this array must contain the lower
-C             triangular part of the absolute residual matrix R, with
-C             bounds on rounding errors added.
-C             On exit, the leading N-by-N part of this array contains
-C             the symmetric absolute residual matrix R (with bounds on
-C             rounding errors added), fully stored.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,N).
-C
-C     FERR    (output) DOUBLE PRECISION
-C             An estimated forward error bound for the solution X.
-C             If XTRUE is the true solution, FERR bounds the magnitude
-C             of the largest entry in (X - XTRUE) divided by the
-C             magnitude of the largest entry in X.
-C             If N = 0 or XANORM = 0, FERR is set to 0, without any
-C             calculations.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N*N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 0,            if N = 0;
-C             LDWORK >= MAX(3,2*N*N), if N > 0.
-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             = N+1:  if T has almost reciprocal eigenvalues; perturbed
-C                   values were used to solve Lyapunov equations (but
-C                   the matrix T is unchanged).
-C
-C     METHOD
-C
-C     The forward error bound is estimated using a practical error bound
-C     similar to the one proposed in [1], based on the 1-norm estimator
-C     in [2].
-C
-C     REFERENCES
-C
-C     [1] Higham, N.J.
-C         Perturbation theory and backward error for AX-XB=C.
-C         BIT, vol. 33, pp. 124-136, 1993.
-C
-C     [2] Higham, N.J.
-C         FORTRAN codes for estimating the one-norm of a real or
-C         complex matrix, with applications to condition estimation.
-C         ACM Trans. Math. Softw., 14, pp. 381-396, 1988.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations.
-C
-C     FURTHER COMMENTS
-C
-C     The option LYAPUN = 'R' may occasionally produce slightly worse
-C     or better estimates, and it is much faster than the option 'O'.
-C     The routine can be also used as a final step in estimating a
-C     forward error bound for the solution of a discrete-time algebraic
-C     matrix Riccati equation.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Romania,
-C     Oct. 1998. Partly based on DDLSVX (and then SB03SD) by P. Petkov,
-C     Tech. University of Sofia, March 1998 (and December 1998).
-C
-C     REVISIONS
-C
-C     February 6, 1999, V. Sima, Katholieke Univ. Leuven, Belgium.
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2004.
-C
-C     KEYWORDS
-C
-C     Lyapunov equation, orthogonal transformation, real Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, HALF
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, HALF = 0.5D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          LYAPUN, TRANA, UPLO
-      INTEGER            INFO, LDR, LDT, LDU, LDWORK, N
-      DOUBLE PRECISION   FERR, XANORM
-C     ..
-C     .. Array Arguments ..
-      INTEGER            IWORK( * )
-      DOUBLE PRECISION   DWORK( * ), R( LDR, * ), T( LDT, * ),
-     $                   U( LDU, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            LOWER, NOTRNA, UPDATE
-      CHARACTER          TRANAT, UPLOW
-      INTEGER            I, IJ, INFO2, ITMP, J, KASE, NN
-      DOUBLE PRECISION   EST, SCALE, TEMP
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DLANSY
-      EXTERNAL           DLANSY, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DLACON, DSCAL, MA02ED, MB01RU, SB03MX, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode and Test input parameters.
-C
-      NOTRNA = LSAME( TRANA,  'N' )
-      UPDATE = LSAME( LYAPUN, 'O' )
-C
-      NN   = N*N
-      INFO = 0
-      IF( .NOT.( NOTRNA .OR. LSAME( TRANA, 'T' ) .OR.
-     $                       LSAME( TRANA, 'C' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( LSAME( UPLO, 'L' ) .OR. LSAME( UPLO, 'U' ) ) )
-     $   THEN
-         INFO = -2
-      ELSE IF( .NOT.( UPDATE .OR. LSAME( LYAPUN, 'R' ) ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( XANORM.LT.ZERO ) THEN
-         INFO = -5
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( LDU.LT.1 .OR. ( UPDATE .AND. LDU.LT.N ) ) THEN
-         INFO = -9
-      ELSE IF( LDR.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDWORK.LT.0 .OR.
-     $       ( LDWORK.LT.MAX( 3, 2*NN ) .AND. N.GT.0 ) ) THEN
-         INFO = -15
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'SB03SX', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      FERR = ZERO
-      IF( N.EQ.0 .OR. XANORM.EQ.ZERO )
-     $   RETURN
-C
-      ITMP = NN + 1
-C
-      IF( NOTRNA ) THEN
-         TRANAT = 'T'
-      ELSE
-         TRANAT = 'N'
-      END IF
-C
-C     Fill in the remaining triangle of the symmetric residual matrix.
-C
-      CALL MA02ED( UPLO, N, R, LDR )
-C
-      KASE = 0
-C
-C     REPEAT
-   10 CONTINUE
-      CALL DLACON( NN, DWORK( ITMP ), DWORK, IWORK, EST, KASE )
-      IF( KASE.NE.0 ) THEN
-C
-C        Select the triangular part of symmetric matrix to be used.
-C
-         IF( DLANSY( '1-norm', 'Upper', N, DWORK, N, DWORK( ITMP ) )
-     $       .GE.
-     $       DLANSY( '1-norm', 'Lower', N, DWORK, N, DWORK( ITMP ) )
-     $     ) THEN
-            UPLOW = 'U'
-            LOWER = .FALSE.
-         ELSE
-            UPLOW = 'L'
-            LOWER = .TRUE.
-         END IF
-C
-         IF( KASE.EQ.2 ) THEN
-            IJ = 0
-            IF( LOWER ) THEN
-C
-C              Scale the lower triangular part of symmetric matrix
-C              by the residual matrix.
-C
-               DO 30 J = 1, N
-                  DO 20 I = J, N
-                     IJ = IJ + 1
-                     DWORK( IJ ) = DWORK( IJ )*R( I, J )
-   20             CONTINUE
-                  IJ = IJ + J
-   30          CONTINUE
-            ELSE
-C
-C              Scale the upper triangular part of symmetric matrix
-C              by the residual matrix.
-C
-               DO 50 J = 1, N
-                  DO 40 I = 1, J
-                     IJ = IJ + 1
-                     DWORK( IJ ) = DWORK( IJ )*R( I, J )
-   40             CONTINUE
-                  IJ = IJ + N - J
-   50          CONTINUE
-            END IF
-         END IF
-C
-         IF( UPDATE ) THEN
-C
-C           Transform the right-hand side: RHS := U'*RHS*U.
-C
-            CALL MB01RU( UPLOW, 'Transpose', N, N, ZERO, ONE, DWORK, N,
-     $                   U, LDU, DWORK, N, DWORK( ITMP ), NN, INFO2 )
-            CALL DSCAL( N, HALF, DWORK, N+1 )
-         END IF
-         CALL MA02ED( UPLOW, N, DWORK, N )
-C
-         IF( KASE.EQ.2 ) THEN
-C
-C           Solve op(T)'*Y*op(T) - Y = scale*RHS.
-C
-            CALL SB03MX( TRANA, N, T, LDT, DWORK, N, SCALE,
-     $                   DWORK( ITMP ), INFO2 )
-         ELSE
-C
-C           Solve op(T)*W*op(T)' - W = scale*RHS.
-C
-            CALL SB03MX( TRANAT, N, T, LDT, DWORK, N, SCALE,
-     $                   DWORK( ITMP ), INFO2 )
-         END IF
-C
-         IF( INFO2.GT.0 )
-     $      INFO = N + 1
-C
-         IF( UPDATE ) THEN
-C
-C           Transform back to obtain the solution: Z := U*Z*U', with
-C           Z = Y or Z = W.
-C
-            CALL MB01RU( UPLOW, 'No transpose', N, N, ZERO, ONE, DWORK,
-     $                   N, U, LDU, DWORK, N, DWORK( ITMP ), NN, INFO2 )
-            CALL DSCAL( N, HALF, DWORK, N+1 )
-         END IF
-C
-         IF( KASE.EQ.1 ) THEN
-            IJ = 0
-            IF( LOWER ) THEN
-C
-C              Scale the lower triangular part of symmetric matrix
-C              by the residual matrix.
-C
-               DO 70 J = 1, N
-                  DO 60 I = J, N
-                     IJ = IJ + 1
-                     DWORK( IJ ) = DWORK( IJ )*R( I, J )
-   60             CONTINUE
-                  IJ = IJ + J
-   70          CONTINUE
-            ELSE
-C
-C              Scale the upper triangular part of symmetric matrix
-C              by the residual matrix.
-C
-               DO 90 J = 1, N
-                  DO 80 I = 1, J
-                     IJ = IJ + 1
-                     DWORK( IJ ) = DWORK( IJ )*R( I, J )
-   80             CONTINUE
-                  IJ = IJ + N - J
-   90          CONTINUE
-            END IF
-         END IF
-C
-C        Fill in the remaining triangle of the symmetric matrix.
-C
-         CALL MA02ED( UPLOW, N, DWORK, N )
-         GO TO 10
-      END IF
-C
-C     UNTIL KASE = 0
-C
-C     Compute the estimate of the relative error.
-C
-      TEMP = XANORM*SCALE
-      IF( TEMP.GT.EST ) THEN
-         FERR = EST / TEMP
-      ELSE
-         FERR = ONE
-      END IF
-C
-      RETURN
-C
-C *** Last line of SB03SX ***
-      END
--- a/extra/control-devel/src/SB03SY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,451 +0,0 @@
-      SUBROUTINE SB03SY( JOB, TRANA, LYAPUN, N, T, LDT, U, LDU, XA,
-     $                   LDXA, SEPD, THNORM, 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 estimate the "separation" between the matrices op(A) and
-C     op(A)',
-C
-C     sepd(op(A),op(A)') = min norm(op(A)'*X*op(A) - X)/norm(X)
-C                        = 1 / norm(inv(Omega))
-C
-C     and/or the 1-norm of Theta, where op(A) = A or A' (A**T), and
-C     Omega and Theta are linear operators associated to the real
-C     discrete-time Lyapunov matrix equation
-C
-C            op(A)'*X*op(A) - X = C,
-C
-C     defined by
-C
-C     Omega(W) = op(A)'*W*op(A) - W,
-C     Theta(W) = inv(Omega(op(W)'*X*op(A) + op(A)'*X*op(W))).
-C
-C     The 1-norm condition estimators are used.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Specifies the computation to be performed, as follows:
-C             = 'S':  Compute the separation only;
-C             = 'T':  Compute the norm of Theta only;
-C             = 'B':  Compute both the separation and the norm of Theta.
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     LYAPUN  CHARACTER*1
-C             Specifies whether or not the original Lyapunov equations
-C             should be solved, as follows:
-C             = 'O':  Solve the original Lyapunov equations, updating
-C                     the right-hand sides and solutions with the
-C                     matrix U, e.g., X <-- U'*X*U;
-C             = 'R':  Solve reduced Lyapunov equations only, without
-C                     updating the right-hand sides and solutions.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrices A and X.  N >= 0.
-C
-C     T       (input) DOUBLE PRECISION array, dimension (LDT,N)
-C             The leading N-by-N upper Hessenberg part of this array
-C             must contain the upper quasi-triangular matrix T in Schur
-C             canonical form from a Schur factorization of A.
-C
-C     LDT     INTEGER
-C             The leading dimension of array T.  LDT >= MAX(1,N).
-C
-C     U       (input) DOUBLE PRECISION array, dimension (LDU,N)
-C             The leading N-by-N part of this array must contain the
-C             orthogonal matrix U from a real Schur factorization of A.
-C             If LYAPUN = 'R', the array U is not referenced.
-C
-C     LDU     INTEGER
-C             The leading dimension of array U.
-C             LDU >= 1,        if LYAPUN = 'R';
-C             LDU >= MAX(1,N), if LYAPUN = 'O'.
-C
-C     XA      (input) DOUBLE PRECISION array, dimension (LDXA,N)
-C             The leading N-by-N part of this array must contain the
-C             matrix product X*op(A), if LYAPUN = 'O', or U'*X*U*op(T),
-C             if LYAPUN = 'R', in the Lyapunov equation.
-C             If JOB = 'S', the array XA is not referenced.
-C
-C     LDXA    INTEGER
-C             The leading dimension of array XA.
-C             LDXA >= 1,        if JOB = 'S';
-C             LDXA >= MAX(1,N), if JOB = 'T' or 'B'.
-C
-C     SEPD    (output) DOUBLE PRECISION
-C             If JOB = 'S' or JOB = 'B', and INFO >= 0, SEPD contains
-C             the estimated quantity sepd(op(A),op(A)').
-C             If JOB = 'T' or N = 0, SEPD is not referenced.
-C
-C     THNORM  (output) DOUBLE PRECISION
-C             If JOB = 'T' or JOB = 'B', and INFO >= 0, THNORM contains
-C             the estimated 1-norm of operator Theta.
-C             If JOB = 'S' or N = 0, THNORM is not referenced.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N*N)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 0,            if N = 0;
-C             LDWORK >= MAX(3,2*N*N), if N > 0.
-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             = N+1:  if T has (almost) reciprocal eigenvalues;
-C                   perturbed values were used to solve Lyapunov
-C                   equations (but the matrix T is unchanged).
-C
-C     METHOD
-C
-C     SEPD is defined as
-C
-C            sepd( op(A), op(A)' ) = sigma_min( K )
-C
-C     where sigma_min(K) is the smallest singular value of the
-C     N*N-by-N*N matrix
-C
-C        K = kprod( op(A)', op(A)' ) - I(N**2).
-C
-C     I(N**2) is an N*N-by-N*N identity matrix, and kprod denotes the
-C     Kronecker product. The routine estimates sigma_min(K) by the
-C     reciprocal of an estimate of the 1-norm of inverse(K), computed as
-C     suggested in [1]. This involves the solution of several discrete-
-C     time Lyapunov equations, either direct or transposed. The true
-C     reciprocal 1-norm of inverse(K) cannot differ from sigma_min(K) by
-C     more than a factor of N.
-C     The 1-norm of Theta is estimated similarly.
-C
-C     REFERENCES
-C
-C     [1] Higham, N.J.
-C         FORTRAN codes for estimating the one-norm of a real or
-C         complex matrix, with applications to condition estimation.
-C         ACM Trans. Math. Softw., 14, pp. 381-396, 1988.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations.
-C
-C     FURTHER COMMENTS
-C
-C     When SEPD is zero, the routine returns immediately, with THNORM
-C     (if requested) not set. In this case, the equation is singular.
-C     The option LYAPUN = 'R' may occasionally produce slightly worse
-C     or better estimates, and it is much faster than the option 'O'.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Romania,
-C     Oct. 1998. Partly based on DDLSVX (and then SB03SD) by P. Petkov,
-C     Tech. University of Sofia, March 1998 (and December 1998).
-C
-C     REVISIONS
-C
-C     February 6, 1999, V. Sima, Katholieke Univ. Leuven, Belgium.
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2004.
-C
-C     KEYWORDS
-C
-C     Lyapunov equation, orthogonal transformation, real Schur form.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, HALF
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, HALF = 0.5D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          JOB, LYAPUN, TRANA
-      INTEGER            INFO, LDT, LDU, LDWORK, LDXA, N
-      DOUBLE PRECISION   SEPD, THNORM
-C     ..
-C     .. Array Arguments ..
-      INTEGER            IWORK( * )
-      DOUBLE PRECISION   DWORK( * ), T( LDT, * ), U( LDU, * ),
-     $                   XA( LDXA, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            NOTRNA, UPDATE, WANTS, WANTT
-      CHARACTER          TRANAT, UPLO
-      INTEGER            INFO2, ITMP, KASE, NN
-      DOUBLE PRECISION   BIGNUM, EST, SCALE
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DLAMCH, DLANSY
-      EXTERNAL           DLAMCH, DLANSY, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DLACON, DLACPY, DSCAL, DSYR2K, MA02ED, MB01RU,
-     $                   SB03MX, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode and Test input parameters.
-C
-      WANTS  = LSAME( JOB,    'S' )
-      WANTT  = LSAME( JOB,    'T' )
-      NOTRNA = LSAME( TRANA,  'N' )
-      UPDATE = LSAME( LYAPUN, 'O' )
-C
-      NN   = N*N
-      INFO = 0
-      IF( .NOT. ( WANTS .OR. WANTT .OR. LSAME( JOB, 'B' ) ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( NOTRNA .OR. LSAME( TRANA, 'T' ) .OR.
-     $                            LSAME( TRANA, 'C' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT.( UPDATE .OR. LSAME( LYAPUN, 'R' ) ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDU.LT.1 .OR. ( UPDATE .AND. LDU.LT.N ) ) THEN
-         INFO = -8
-      ELSE IF( LDXA.LT.1 .OR. ( .NOT.WANTS .AND. LDXA.LT.N ) ) THEN
-         INFO = -10
-      ELSE IF( LDWORK.LT.0 .OR.
-     $       ( LDWORK.LT.MAX( 3, 2*NN ) .AND. N.GT.0 ) ) THEN
-         INFO = -15
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'SB03SY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( N.EQ.0 )
-     $   RETURN
-C
-      ITMP = NN + 1
-C
-      IF( NOTRNA ) THEN
-         TRANAT = 'T'
-      ELSE
-         TRANAT = 'N'
-      END IF
-C
-      IF( .NOT.WANTT ) THEN
-C
-C        Estimate sepd(op(A),op(A)').
-C        Workspace:  max(3,2*N*N).
-C
-         KASE = 0
-C
-C        REPEAT
-   10    CONTINUE
-         CALL DLACON( NN, DWORK( ITMP ), DWORK, IWORK, EST, KASE )
-         IF( KASE.NE.0 ) THEN
-C
-C           Select the triangular part of symmetric matrix to be used.
-C
-            IF( DLANSY( '1-norm', 'Upper', N, DWORK, N, DWORK( ITMP ) )
-     $          .GE.
-     $          DLANSY( '1-norm', 'Lower', N, DWORK, N, DWORK( ITMP ) )
-     $        ) THEN
-               UPLO = 'U'
-            ELSE
-               UPLO = 'L'
-            END IF
-C
-            IF( UPDATE ) THEN
-C
-C              Transform the right-hand side: RHS := U'*RHS*U.
-C
-               CALL MB01RU( UPLO, 'Transpose', N, N, ZERO, ONE, DWORK,
-     $                      N, U, LDU, DWORK, N, DWORK( ITMP ), NN,
-     $                      INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-            END IF
-            CALL MA02ED( UPLO, N, DWORK, N )
-C
-            IF( KASE.EQ.1 ) THEN
-C
-C              Solve op(T)'*Y*op(T) - Y = scale*RHS.
-C
-               CALL SB03MX( TRANA, N, T, LDT, DWORK, N, SCALE,
-     $                      DWORK( ITMP ), INFO2 )
-            ELSE
-C
-C              Solve op(T)*W*op(T)' - W = scale*RHS.
-C
-               CALL SB03MX( TRANAT, N, T, LDT, DWORK, N, SCALE,
-     $                      DWORK( ITMP ), INFO2 )
-            END IF
-C
-            IF( INFO2.GT.0 )
-     $         INFO = N + 1
-C
-            IF( UPDATE ) THEN
-C
-C              Transform back to obtain the solution: Z := U*Z*U', with
-C              Z = Y or Z = W.
-C
-               CALL MB01RU( UPLO, 'No transpose', N, N, ZERO, ONE,
-     $                      DWORK, N, U, LDU, DWORK, N, DWORK( ITMP ),
-     $                      NN, INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-C
-C              Fill in the remaining triangle of the symmetric matrix.
-C
-               CALL MA02ED( UPLO, N, DWORK, N )
-            END IF
-C
-            GO TO 10
-         END IF
-C        UNTIL KASE = 0
-C
-         IF( EST.GT.SCALE ) THEN
-            SEPD = SCALE / EST
-         ELSE
-            BIGNUM = ONE / DLAMCH( 'Safe minimum' )
-            IF( SCALE.LT.EST*BIGNUM ) THEN
-               SEPD = SCALE / EST
-            ELSE
-               SEPD = BIGNUM
-            END IF
-         END IF
-C
-C        Return if the equation is singular.
-C
-         IF( SEPD.EQ.ZERO )
-     $      RETURN
-      END IF
-C
-      IF( .NOT.WANTS ) THEN
-C
-C        Estimate norm(Theta).
-C        Workspace:  max(3,2*N*N).
-C
-         KASE = 0
-C
-C        REPEAT
-   20    CONTINUE
-         CALL DLACON( NN, DWORK( ITMP ), DWORK, IWORK, EST, KASE )
-         IF( KASE.NE.0 ) THEN
-C
-C           Select the triangular part of symmetric matrix to be used.
-C
-            IF( DLANSY( '1-norm', 'Upper', N, DWORK, N, DWORK( ITMP ) )
-     $          .GE.
-     $          DLANSY( '1-norm', 'Lower', N, DWORK, N, DWORK( ITMP ) )
-     $        ) THEN
-               UPLO = 'U'
-            ELSE
-               UPLO = 'L'
-            END IF
-C
-C           Fill in the remaining triangle of the symmetric matrix.
-C
-            CALL MA02ED( UPLO, N, DWORK, N )
-C
-C           Compute RHS = op(W)'*X*op(A) + op(A)'*X*op(W).
-C
-            CALL DSYR2K( UPLO, TRANAT, N, N, ONE, DWORK, N, XA, LDXA,
-     $                   ZERO, DWORK( ITMP ), N )
-            CALL DLACPY( UPLO, N, N, DWORK( ITMP ), N, DWORK, N )
-C
-            IF( UPDATE ) THEN
-C
-C              Transform the right-hand side: RHS := U'*RHS*U.
-C
-               CALL MB01RU( UPLO, 'Transpose', N, N, ZERO, ONE, DWORK,
-     $                      N, U, LDU, DWORK, N, DWORK( ITMP ), NN,
-     $                      INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-            END IF
-            CALL MA02ED( UPLO, N, DWORK, N )
-C
-            IF( KASE.EQ.1 ) THEN
-C
-C              Solve op(T)'*Y*op(T) - Y = scale*RHS.
-C
-               CALL SB03MX( TRANA, N, T, LDT, DWORK, N, SCALE,
-     $                      DWORK( ITMP ), INFO2 )
-            ELSE
-C
-C              Solve op(T)*W*op(T)' - W = scale*RHS.
-C
-               CALL SB03MX( TRANAT, N, T, LDT, DWORK, N, SCALE,
-     $                      DWORK( ITMP ), INFO2 )
-            END IF
-C
-            IF( INFO2.GT.0 )
-     $         INFO = N + 1
-C
-            IF( UPDATE ) THEN
-C
-C              Transform back to obtain the solution: Z := U*Z*U', with
-C              Z = Y or Z = W.
-C
-               CALL MB01RU( UPLO, 'No transpose', N, N, ZERO, ONE,
-     $                      DWORK, N, U, LDU, DWORK, N, DWORK( ITMP ),
-     $                      NN, INFO2 )
-               CALL DSCAL( N, HALF, DWORK, N+1 )
-C
-C              Fill in the remaining triangle of the symmetric matrix.
-C
-               CALL MA02ED( UPLO, N, DWORK, N )
-            END IF
-C
-            GO TO 20
-         END IF
-C        UNTIL KASE = 0
-C
-         IF( EST.LT.SCALE ) THEN
-            THNORM = EST / SCALE
-         ELSE
-            BIGNUM = ONE / DLAMCH( 'Safe minimum' )
-            IF( EST.LT.SCALE*BIGNUM ) THEN
-               THNORM = EST / SCALE
-            ELSE
-               THNORM = BIGNUM
-            END IF
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of SB03SY ***
-      END
--- a/extra/control-devel/src/SB04PX.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,468 +0,0 @@
-      SUBROUTINE SB04PX( LTRANL, LTRANR, ISGN, N1, N2, TL, LDTL, TR,
-     $                   LDTR, B, LDB, SCALE, X, LDX, XNORM, 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 the N1-by-N2 matrix X, 1 <= N1,N2 <= 2, in
-C
-C            op(TL)*X*op(TR) + ISGN*X = SCALE*B,
-C
-C     where TL is N1-by-N1, TR is N2-by-N2, B is N1-by-N2, and ISGN = 1
-C     or -1.  op(T) = T or T', where T' denotes the transpose of T.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     LTRANL  LOGICAL
-C             Specifies the form of op(TL) to be used, as follows:
-C             = .FALSE.:  op(TL) = TL,
-C             = .TRUE. :  op(TL) = TL'.
-C
-C     LTRANR  LOGICAL
-C             Specifies the form of op(TR) to be used, as follows:
-C             = .FALSE.:  op(TR) = TR,
-C             = .TRUE. :  op(TR) = TR'.
-C
-C     ISGN    INTEGER
-C             Specifies the sign of the equation as described before.
-C             ISGN may only be 1 or -1.
-C
-C     Input/Output Parameters
-C
-C     N1      (input) INTEGER
-C             The order of matrix TL.  N1 may only be 0, 1 or 2.
-C
-C     N2      (input) INTEGER
-C             The order of matrix TR.  N2 may only be 0, 1 or 2.
-C
-C     TL      (input) DOUBLE PRECISION array, dimension (LDTL,N1)
-C             The leading N1-by-N1 part of this array must contain the
-C             matrix TL.
-C
-C     LDTL    INTEGER
-C             The leading dimension of array TL.  LDTL >= MAX(1,N1).
-C
-C     TR      (input) DOUBLE PRECISION array, dimension (LDTR,N2)
-C             The leading N2-by-N2 part of this array must contain the
-C             matrix TR.
-C
-C     LDTR    INTEGER
-C             The leading dimension of array TR.  LDTR >= MAX(1,N2).
-C
-C     B       (input) DOUBLE PRECISION array, dimension (LDB,N2)
-C             The leading N1-by-N2 part of this array must contain the
-C             right-hand side of the equation.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N1).
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor. SCALE is chosen less than or equal to 1
-C             to prevent the solution overflowing.
-C
-C     X       (output) DOUBLE PRECISION array, dimension (LDX,N2)
-C             The leading N1-by-N2 part of this array contains the
-C             solution of the equation.
-C             Note that X may be identified with B in the calling
-C             statement.
-C
-C     LDX     INTEGER
-C             The leading dimension of array X.  LDX >= MAX(1,N1).
-C
-C     XNORM   (output) DOUBLE PRECISION
-C             The infinity-norm of the solution.
-C
-C     Error Indicator
-C
-C     INFO    INTEGER
-C             = 0:  successful exit;
-C             = 1:  if TL and -ISGN*TR have almost reciprocal
-C                   eigenvalues, so TL or TR is perturbed to get a
-C                   nonsingular equation.
-C
-C             NOTE: In the interests of speed, this routine does not
-C                   check the inputs for errors.
-C
-C     METHOD
-C
-C     The equivalent linear algebraic system of equations is formed and
-C     solved using Gaussian elimination with complete pivoting.
-C
-C     REFERENCES
-C
-C     [1] Anderson, E., Bai, Z., Bischof, C., Demmel, J., Dongarra, J.,
-C         Du Croz, J., Greenbaum, A., Hammarling, S., McKenney, A.,
-C         Ostrouchov, S., and Sorensen, D.
-C         LAPACK Users' Guide: Second Edition.
-C         SIAM, Philadelphia, 1995.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is stable and reliable, since Gaussian elimination
-C     with complete pivoting is used.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, May 2000.
-C     This is a modification and slightly more efficient version of
-C     SLICOT Library routine SB03MU.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Discrete-time system, Sylvester equation, matrix algebra.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE, TWO, HALF, EIGHT
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0,
-     $                     TWO = 2.0D+0, HALF = 0.5D+0, EIGHT = 8.0D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      LOGICAL            LTRANL, LTRANR
-      INTEGER            INFO, ISGN, LDB, LDTL, LDTR, LDX, N1, N2
-      DOUBLE PRECISION   SCALE, XNORM
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   B( LDB, * ), TL( LDTL, * ), TR( LDTR, * ),
-     $                   X( LDX, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            BSWAP, XSWAP
-      INTEGER            I, IP, IPIV, IPSV, J, JP, JPSV, K
-      DOUBLE PRECISION   BET, EPS, GAM, L21, SGN, SMIN, SMLNUM, TAU1,
-     $                   TEMP, U11, U12, U22, XMAX
-C     ..
-C     .. Local Arrays ..
-      LOGICAL            BSWPIV( 4 ), XSWPIV( 4 )
-      INTEGER            JPIV( 4 ), LOCL21( 4 ), LOCU12( 4 ),
-     $                   LOCU22( 4 )
-      DOUBLE PRECISION   BTMP( 4 ), T16( 4, 4 ), TMP( 4 ), X2( 2 )
-C     ..
-C     .. External Functions ..
-      INTEGER            IDAMAX
-      DOUBLE PRECISION   DLAMCH
-      EXTERNAL           DLAMCH, IDAMAX
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DSWAP
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, MAX
-C     ..
-C     .. Data statements ..
-      DATA               LOCU12 / 3, 4, 1, 2 / , LOCL21 / 2, 1, 4, 3 / ,
-     $                   LOCU22 / 4, 3, 2, 1 /
-      DATA               XSWPIV / .FALSE., .FALSE., .TRUE., .TRUE. /
-      DATA               BSWPIV / .FALSE., .TRUE., .FALSE., .TRUE. /
-C     ..
-C     .. Executable Statements ..
-C
-C     Do not check the input parameters for errors.
-C
-      INFO  = 0
-      SCALE = ONE
-C
-C     Quick return if possible.
-C
-      IF( N1.EQ.0 .OR. N2.EQ.0 ) THEN
-         XNORM = ZERO
-         RETURN
-      END IF
-C
-C     Set constants to control overflow.
-C
-      EPS = DLAMCH( 'P' )
-      SMLNUM = DLAMCH( 'S' ) / EPS
-      SGN = ISGN
-C
-      K = N1 + N1 + N2 - 2
-      GO TO ( 10, 20, 30, 50 )K
-C
-C     1-by-1: TL11*X*TR11 + ISGN*X = B11.
-C
-   10 CONTINUE
-      TAU1 = TL( 1, 1 )*TR( 1, 1 ) + SGN
-      BET  = ABS( TAU1 )
-      IF( BET.LE.SMLNUM ) THEN
-         TAU1 = SMLNUM
-         BET  = SMLNUM
-         INFO = 1
-      END IF
-C
-      GAM = ABS( B( 1, 1 ) )
-      IF( SMLNUM*GAM.GT.BET )
-     $   SCALE = ONE / GAM
-C
-      X( 1, 1 ) = ( B( 1, 1 )*SCALE ) / TAU1
-      XNORM = ABS( X( 1, 1 ) )
-      RETURN
-C
-C     1-by-2:
-C     TL11*[X11 X12]*op[TR11 TR12] + ISGN*[X11 X12] = [B11 B12].
-C                      [TR21 TR22]
-C
-   20 CONTINUE
-C
-      SMIN = MAX( MAX( ABS( TR( 1, 1 ) ), ABS( TR( 1, 2 ) ),
-     $                 ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) )
-     $                *ABS( TL( 1, 1 ) )*EPS,
-     $            SMLNUM )
-      TMP( 1 ) = TL( 1, 1 )*TR( 1, 1 ) + SGN
-      TMP( 4 ) = TL( 1, 1 )*TR( 2, 2 ) + SGN
-      IF( LTRANR ) THEN
-         TMP( 2 ) = TL( 1, 1 )*TR( 2, 1 )
-         TMP( 3 ) = TL( 1, 1 )*TR( 1, 2 )
-      ELSE
-         TMP( 2 ) = TL( 1, 1 )*TR( 1, 2 )
-         TMP( 3 ) = TL( 1, 1 )*TR( 2, 1 )
-      END IF
-      BTMP( 1 ) = B( 1, 1 )
-      BTMP( 2 ) = B( 1, 2 )
-      GO TO 40
-C
-C     2-by-1:
-C     op[TL11 TL12]*[X11]*TR11 + ISGN*[X11] = [B11].
-C       [TL21 TL22] [X21]             [X21]   [B21]
-C
-   30 CONTINUE
-      SMIN = MAX( MAX( ABS( TL( 1, 1 ) ), ABS( TL( 1, 2 ) ),
-     $                 ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) )
-     $                *ABS( TR( 1, 1 ) )*EPS,
-     $            SMLNUM )
-      TMP( 1 ) = TL( 1, 1 )*TR( 1, 1 ) + SGN
-      TMP( 4 ) = TL( 2, 2 )*TR( 1, 1 ) + SGN
-      IF( LTRANL ) THEN
-         TMP( 2 ) = TL( 1, 2 )*TR( 1, 1 )
-         TMP( 3 ) = TL( 2, 1 )*TR( 1, 1 )
-      ELSE
-         TMP( 2 ) = TL( 2, 1 )*TR( 1, 1 )
-         TMP( 3 ) = TL( 1, 2 )*TR( 1, 1 )
-      END IF
-      BTMP( 1 ) = B( 1, 1 )
-      BTMP( 2 ) = B( 2, 1 )
-   40 CONTINUE
-C
-C     Solve 2-by-2 system using complete pivoting.
-C     Set pivots less than SMIN to SMIN.
-C
-      IPIV = IDAMAX( 4, TMP, 1 )
-      U11  = TMP( IPIV )
-      IF( ABS( U11 ).LE.SMIN ) THEN
-         INFO = 1
-         U11  = SMIN
-      END IF
-      U12 = TMP( LOCU12( IPIV ) )
-      L21 = TMP( LOCL21( IPIV ) ) / U11
-      U22 = TMP( LOCU22( IPIV ) ) - U12*L21
-      XSWAP = XSWPIV( IPIV )
-      BSWAP = BSWPIV( IPIV )
-      IF( ABS( U22 ).LE.SMIN ) THEN
-         INFO = 1
-         U22  = SMIN
-      END IF
-      IF( BSWAP ) THEN
-         TEMP = BTMP( 2 )
-         BTMP( 2 ) = BTMP( 1 ) - L21*TEMP
-         BTMP( 1 ) = TEMP
-      ELSE
-         BTMP( 2 ) = BTMP( 2 ) - L21*BTMP( 1 )
-      END IF
-      IF( ( TWO*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( U22 ) .OR.
-     $    ( TWO*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( U11 ) ) THEN
-         SCALE = HALF / MAX( ABS( BTMP( 1 ) ), ABS( BTMP( 2 ) ) )
-         BTMP( 1 ) = BTMP( 1 )*SCALE
-         BTMP( 2 ) = BTMP( 2 )*SCALE
-      END IF
-      X2( 2 ) = BTMP( 2 ) / U22
-      X2( 1 ) = BTMP( 1 ) / U11 - ( U12 / U11 )*X2( 2 )
-      IF( XSWAP ) THEN
-         TEMP = X2( 2 )
-         X2( 2 ) = X2( 1 )
-         X2( 1 ) = TEMP
-      END IF
-      X( 1, 1 ) = X2( 1 )
-      IF( N1.EQ.1 ) THEN
-         X( 1, 2 ) = X2( 2 )
-         XNORM = ABS( X2( 1 ) ) + ABS( X2( 2 ) )
-      ELSE
-         X( 2, 1 ) = X2( 2 )
-         XNORM = MAX( ABS( X2( 1 ) ), ABS( X2( 2 ) ) )
-      END IF
-      RETURN
-C
-C     2-by-2:
-C     op[TL11 TL12]*[X11 X12]*op[TR11 TR12] + ISGN*[X11 X12] = [B11 B12]
-C       [TL21 TL22] [X21 X22]   [TR21 TR22]        [X21 X22]   [B21 B22]
-C
-C     Solve equivalent 4-by-4 system using complete pivoting.
-C     Set pivots less than SMIN to SMIN.
-C
-   50 CONTINUE
-      SMIN = MAX( ABS( TR( 1, 1 ) ), ABS( TR( 1, 2 ) ),
-     $            ABS( TR( 2, 1 ) ), ABS( TR( 2, 2 ) ) )
-      SMIN = MAX( ABS( TL( 1, 1 ) ), ABS( TL( 1, 2 ) ),
-     $            ABS( TL( 2, 1 ) ), ABS( TL( 2, 2 ) ) )*SMIN
-      SMIN = MAX( EPS*SMIN, SMLNUM )
-      T16( 1, 1 ) = TL( 1, 1 )*TR( 1, 1 ) + SGN
-      T16( 2, 2 ) = TL( 2, 2 )*TR( 1, 1 ) + SGN
-      T16( 3, 3 ) = TL( 1, 1 )*TR( 2, 2 ) + SGN
-      T16( 4, 4 ) = TL( 2, 2 )*TR( 2, 2 ) + SGN
-      IF( LTRANL ) THEN
-         T16( 1, 2 ) = TL( 2, 1 )*TR( 1, 1 )
-         T16( 2, 1 ) = TL( 1, 2 )*TR( 1, 1 )
-         T16( 3, 4 ) = TL( 2, 1 )*TR( 2, 2 )
-         T16( 4, 3 ) = TL( 1, 2 )*TR( 2, 2 )
-      ELSE
-         T16( 1, 2 ) = TL( 1, 2 )*TR( 1, 1 )
-         T16( 2, 1 ) = TL( 2, 1 )*TR( 1, 1 )
-         T16( 3, 4 ) = TL( 1, 2 )*TR( 2, 2 )
-         T16( 4, 3 ) = TL( 2, 1 )*TR( 2, 2 )
-      END IF
-      IF( LTRANR ) THEN
-         T16( 1, 3 ) = TL( 1, 1 )*TR( 1, 2 )
-         T16( 2, 4 ) = TL( 2, 2 )*TR( 1, 2 )
-         T16( 3, 1 ) = TL( 1, 1 )*TR( 2, 1 )
-         T16( 4, 2 ) = TL( 2, 2 )*TR( 2, 1 )
-      ELSE
-         T16( 1, 3 ) = TL( 1, 1 )*TR( 2, 1 )
-         T16( 2, 4 ) = TL( 2, 2 )*TR( 2, 1 )
-         T16( 3, 1 ) = TL( 1, 1 )*TR( 1, 2 )
-         T16( 4, 2 ) = TL( 2, 2 )*TR( 1, 2 )
-      END IF
-      IF( LTRANL .AND. LTRANR ) THEN
-         T16( 1, 4 ) = TL( 2, 1 )*TR( 1, 2 )
-         T16( 2, 3 ) = TL( 1, 2 )*TR( 1, 2 )
-         T16( 3, 2 ) = TL( 2, 1 )*TR( 2, 1 )
-         T16( 4, 1 ) = TL( 1, 2 )*TR( 2, 1 )
-      ELSE IF( LTRANL .AND. .NOT.LTRANR ) THEN
-         T16( 1, 4 ) = TL( 2, 1 )*TR( 2, 1 )
-         T16( 2, 3 ) = TL( 1, 2 )*TR( 2, 1 )
-         T16( 3, 2 ) = TL( 2, 1 )*TR( 1, 2 )
-         T16( 4, 1 ) = TL( 1, 2 )*TR( 1, 2 )
-      ELSE IF( .NOT.LTRANL .AND. LTRANR ) THEN
-          T16( 1, 4 ) = TL( 1, 2 )*TR( 1, 2 )
-          T16( 2, 3 ) = TL( 2, 1 )*TR( 1, 2 )
-          T16( 3, 2 ) = TL( 1, 2 )*TR( 2, 1 )
-          T16( 4, 1 ) = TL( 2, 1 )*TR( 2, 1 )
-      ELSE
-          T16( 1, 4 ) = TL( 1, 2 )*TR( 2, 1 )
-          T16( 2, 3 ) = TL( 2, 1 )*TR( 2, 1 )
-          T16( 3, 2 ) = TL( 1, 2 )*TR( 1, 2 )
-          T16( 4, 1 ) = TL( 2, 1 )*TR( 1, 2 )
-      END IF
-      BTMP( 1 ) = B( 1, 1 )
-      BTMP( 2 ) = B( 2, 1 )
-      BTMP( 3 ) = B( 1, 2 )
-      BTMP( 4 ) = B( 2, 2 )
-C
-C     Perform elimination.
-C
-      DO 100 I = 1, 3
-         XMAX = ZERO
-C
-         DO 70 IP = I, 4
-C
-            DO 60 JP = I, 4
-               IF( ABS( T16( IP, JP ) ).GE.XMAX ) THEN
-                  XMAX = ABS( T16( IP, JP ) )
-                  IPSV = IP
-                  JPSV = JP
-               END IF
-   60       CONTINUE
-C
-   70    CONTINUE
-C
-         IF( IPSV.NE.I ) THEN
-            CALL DSWAP( 4, T16( IPSV, 1 ), 4, T16( I, 1 ), 4 )
-            TEMP = BTMP( I )
-            BTMP( I ) = BTMP( IPSV )
-            BTMP( IPSV ) = TEMP
-         END IF
-         IF( JPSV.NE.I )
-     $      CALL DSWAP( 4, T16( 1, JPSV ), 1, T16( 1, I ), 1 )
-         JPIV( I ) = JPSV
-         IF( ABS( T16( I, I ) ).LT.SMIN ) THEN
-            INFO = 1
-            T16( I, I ) = SMIN
-         END IF
-C
-         DO 90 J = I + 1, 4
-            T16( J, I ) = T16( J, I ) / T16( I, I )
-            BTMP( J ) = BTMP( J ) - T16( J, I )*BTMP( I )
-C
-            DO 80 K = I + 1, 4
-               T16( J, K ) = T16( J, K ) - T16( J, I )*T16( I, K )
-   80       CONTINUE
-C
-   90    CONTINUE
-C
-  100 CONTINUE
-C
-      IF( ABS( T16( 4, 4 ) ).LT.SMIN )
-     $   T16( 4, 4 ) = SMIN
-      IF( ( EIGHT*SMLNUM )*ABS( BTMP( 1 ) ).GT.ABS( T16( 1, 1 ) ) .OR.
-     $    ( EIGHT*SMLNUM )*ABS( BTMP( 2 ) ).GT.ABS( T16( 2, 2 ) ) .OR.
-     $    ( EIGHT*SMLNUM )*ABS( BTMP( 3 ) ).GT.ABS( T16( 3, 3 ) ) .OR.
-     $    ( EIGHT*SMLNUM )*ABS( BTMP( 4 ) ).GT.ABS( T16( 4, 4 ) ) ) THEN
-         SCALE = ( ONE / EIGHT ) / MAX( ABS( BTMP( 1 ) ),
-     $                ABS( BTMP( 2 ) ), ABS( BTMP( 3 ) ),
-     $                ABS( BTMP( 4 ) ) )
-         BTMP( 1 ) = BTMP( 1 )*SCALE
-         BTMP( 2 ) = BTMP( 2 )*SCALE
-         BTMP( 3 ) = BTMP( 3 )*SCALE
-         BTMP( 4 ) = BTMP( 4 )*SCALE
-      END IF
-C
-      DO 120 I = 1, 4
-         K = 5 - I
-         TEMP = ONE / T16( K, K )
-         TMP( K ) = BTMP( K )*TEMP
-C
-         DO 110 J = K + 1, 4
-            TMP( K ) = TMP( K ) - ( TEMP*T16( K, J ) )*TMP( J )
-  110    CONTINUE
-C
-  120 CONTINUE
-C
-      DO 130 I = 1, 3
-         IF( JPIV( 4-I ).NE.4-I ) THEN
-            TEMP = TMP( 4-I )
-            TMP( 4-I ) = TMP( JPIV( 4-I ) )
-            TMP( JPIV( 4-I ) ) = TEMP
-         END IF
-  130 CONTINUE
-C
-      X( 1, 1 ) = TMP( 1 )
-      X( 2, 1 ) = TMP( 2 )
-      X( 1, 2 ) = TMP( 3 )
-      X( 2, 2 ) = TMP( 4 )
-      XNORM = MAX( ABS( TMP( 1 ) ) + ABS( TMP( 3 ) ),
-     $             ABS( TMP( 2 ) ) + ABS( TMP( 4 ) ) )
-C
-      RETURN
-C *** Last line of SB04PX ***
-      END
--- a/extra/control-devel/src/SB04PY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1111 +0,0 @@
-      SUBROUTINE SB04PY( TRANA, TRANB, ISGN, M, N, A, LDA, B, LDB, C,
-     $                   LDC, SCALE, DWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To solve for X the discrete-time Sylvester equation
-C
-C        op(A)*X*op(B) + ISGN*X = scale*C,
-C
-C     where op(A) = A or A**T, A and B are both upper quasi-triangular,
-C     and ISGN = 1 or -1. A is M-by-M and B is N-by-N; the right hand
-C     side C and the solution X are M-by-N; and scale is an output scale
-C     factor, set less than or equal to 1 to avoid overflow in X. The
-C     solution matrix X is overwritten onto C.
-C
-C     A and B must be in Schur canonical form (as returned by LAPACK
-C     Library routine DHSEQR), that is, block upper triangular with
-C     1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block has
-C     its diagonal elements equal and its off-diagonal elements of
-C     opposite sign.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     TRANA   CHARACTER*1
-C             Specifies the form of op(A) to be used, as follows:
-C             = 'N':  op(A) = A    (No transpose);
-C             = 'T':  op(A) = A**T (Transpose);
-C             = 'C':  op(A) = A**T (Conjugate transpose = Transpose).
-C
-C     TRANB   CHARACTER*1
-C             Specifies the form of op(B) to be used, as follows:
-C             = 'N':  op(B) = B    (No transpose);
-C             = 'T':  op(B) = B**T (Transpose);
-C             = 'C':  op(B) = B**T (Conjugate transpose = Transpose).
-C
-C     ISGN    INTEGER
-C             Specifies the sign of the equation as described before.
-C             ISGN may only be 1 or -1.
-C
-C     Input/Output Parameters
-C
-C     M       (input) INTEGER
-C             The order of the matrix A, and the number of rows in the
-C             matrices X and C.  M >= 0.
-C
-C     N       (input) INTEGER
-C             The order of the matrix B, and the number of columns in
-C             the matrices X and C.  N >= 0.
-C
-C     A       (input) DOUBLE PRECISION array, dimension (LDA,M)
-C             The leading M-by-M part of this array must contain the
-C             upper quasi-triangular matrix A, in Schur canonical form.
-C             The part of A below the first sub-diagonal is not
-C             referenced.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,M).
-C
-C     B       (input) DOUBLE PRECISION array, dimension (LDB,N)
-C             The leading N-by-N part of this array must contain the
-C             upper quasi-triangular matrix B, in Schur canonical form.
-C             The part of B below the first sub-diagonal is not
-C             referenced.
-C
-C     LDB     (input) INTEGER
-C             The leading dimension of the array B.  LDB >= max(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading M-by-N part of this array must
-C             contain the right hand side matrix C.
-C             On exit, if INFO >= 0, the leading M-by-N part of this
-C             array contains the solution matrix X.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,M).
-C
-C     SCALE   (output) DOUBLE PRECISION
-C             The scale factor, scale, set less than or equal to 1 to
-C             prevent the solution overflowing.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (2*M)
-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:  A and -ISGN*B have almost reciprocal eigenvalues;
-C                   perturbed values were used to solve the equation
-C                   (but the matrices A and B are unchanged).
-C
-C     METHOD
-C
-C     The solution matrix X is computed column-wise via a back
-C     substitution scheme, an extension and refinement of the algorithm
-C     in [1], similar to that used in [2] for continuous-time Sylvester
-C     equations. A set of equivalent linear algebraic systems of
-C     equations of order at most four are formed and solved using
-C     Gaussian elimination with complete pivoting.
-C
-C     REFERENCES
-C
-C     [1] Bartels, R.H. and Stewart, G.W.  T
-C         Solution of the matrix equation A X + XB = C.
-C         Comm. A.C.M., 15, pp. 820-826, 1972.
-C
-C     [2] Anderson, E., Bai, Z., Bischof, C., Demmel, J., Dongarra, J.,
-C         Du Croz, J., Greenbaum, A., Hammarling, S., McKenney, A.,
-C         Ostrouchov, S., and Sorensen, D.
-C         LAPACK Users' Guide: Second Edition.
-C         SIAM, Philadelphia, 1995.
-C
-C     NUMERICAL ASPECTS
-C
-C     The algorithm is stable and reliable, since Gaussian elimination
-C     with complete pivoting is used.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, March 2000.
-C     D. Sima, University of Bucharest, April 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Apr. 2000.
-C     Partly based on the routine SYLSV, A. Varga, 1992.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Discrete-time system, matrix algebra, Sylvester equation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          TRANA, TRANB
-      INTEGER            INFO, ISGN, LDA, LDB, LDC, M, N
-      DOUBLE PRECISION   SCALE
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), C( LDC, * ),
-     $                   DWORK( * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            NOTRNA, NOTRNB
-      INTEGER            IERR, J, K, K1, K2, KNEXT, L, L1, L2, LNEXT,
-     $                   MNK1, MNK2, MNL1, MNL2
-      DOUBLE PRECISION   A11, BIGNUM, DA11, DB, EPS, P11, P12, P21, P22,
-     $                   SCALOC, SGN, SMIN, SMLNUM, SUMR, XNORM
-C     ..
-C     .. Local Arrays ..
-      DOUBLE PRECISION   DUM( 1 ), VEC( 2, 2 ), X( 2, 2 )
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      DOUBLE PRECISION   DDOT, DLAMCH, DLANGE
-      EXTERNAL           DDOT, DLAMCH, DLANGE, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DLABAD, DLALN2, DSCAL, SB04PX, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, DBLE, MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-C     Decode and Test input parameters
-C
-      NOTRNA = LSAME( TRANA, 'N' )
-      NOTRNB = LSAME( TRANB, 'N' )
-C
-      INFO = 0
-      IF( .NOT.NOTRNA .AND. .NOT.LSAME( TRANA, 'T' ) .AND.
-     $    .NOT.LSAME( TRANA, 'C' ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.NOTRNB .AND. .NOT.LSAME( TRANB, 'T' ) .AND.
-     $         .NOT.LSAME( TRANB, 'C' ) ) THEN
-         INFO = -2
-      ELSE IF( ISGN.NE.1 .AND. ISGN.NE.-1 ) THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
-         INFO = -7
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( LDC.LT.MAX( 1, M ) ) THEN
-         INFO = -11
-      END IF
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'SB04PY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      SCALE = ONE
-      IF( M.EQ.0 .OR. N.EQ.0 )
-     $   RETURN
-C
-C     Set constants to control overflow.
-C
-      EPS    = DLAMCH( 'Precision' )
-      SMLNUM = DLAMCH( 'Safe minimum' )
-      BIGNUM = ONE / SMLNUM
-      CALL DLABAD( SMLNUM, BIGNUM )
-      SMLNUM = SMLNUM*DBLE( M*N ) / EPS
-      BIGNUM = ONE / SMLNUM
-C
-      SMIN = MAX( SMLNUM, EPS*DLANGE( 'M', M, M, A, LDA, DUM ),
-     $                    EPS*DLANGE( 'M', N, N, B, LDB, DUM ) )
-C
-      SGN = ISGN
-C
-      IF( NOTRNA .AND. NOTRNB ) THEN
-C
-C        Solve    A*X*B + ISGN*X = scale*C.
-C
-C        The (K,L)th block of X is determined starting from
-C        bottom-left corner column by column by
-C
-C           A(K,K)*X(K,L)*B(L,L) + ISGN*X(K,L) = C(K,L) - R(K,L)
-C
-C        where
-C                       M
-C           R(K,L) = { SUM [A(K,J)*X(J,L)] } * B(L,L) +
-C                     J=K+1
-C                       M             L-1
-C                      SUM { A(K,J) * SUM [X(J,I)*B(I,L)] }.
-C                      J=K            I=1
-C
-C        Start column loop (index = L)
-C        L1 (L2) : column index of the first (last) row of X(K,L).
-C
-         LNEXT = 1
-C
-         DO 60 L = 1, N
-            IF( L.LT.LNEXT )
-     $         GO TO 60
-            L1 = L
-            IF( L.EQ.N ) THEN
-               L2 = L
-            ELSE
-               IF( B( L+1, L ).NE.ZERO ) THEN
-                  L2 = L + 1
-               ELSE
-                  L2 = L
-               END IF
-               LNEXT = L2 + 1
-            END IF
-C
-C           Start row loop (index = K)
-C           K1 (K2): row index of the first (last) row of X(K,L).
-C
-            KNEXT = M
-C
-            DO 50 K = M, 1, -1
-               IF( K.GT.KNEXT )
-     $            GO TO 50
-               K2 = K
-               IF( K.EQ.1 ) THEN
-                  K1 = K
-               ELSE
-                  IF( A( K, K-1 ).NE.ZERO ) THEN
-                     K1 = K - 1
-                  ELSE
-                     K1 = K
-                  END IF
-                  KNEXT = K1 - 1
-               END IF
-C
-               MNK1 = MIN( K1+1, M )
-               MNK2 = MIN( K2+1, M )
-               P11  = DDOT( M-K2, A( K1, MNK2 ), LDA, C( MNK2, L1 ), 1 )
-               DWORK( K1 ) = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1 ),
-     $                             1 )
-C
-               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) )
-                  SCALOC = ONE
-C
-                  A11  = A( K1, K1 )*B( L1, L1 ) + SGN
-                  DA11 = ABS( A11 )
-                  IF( DA11.LE.SMIN ) THEN
-                     A11  = SMIN
-                     DA11 = SMIN
-                     INFO = 1
-                  END IF
-                  DB = ABS( VEC( 1, 1 ) )
-                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
-                     IF( DB.GT.BIGNUM*DA11 )
-     $                  SCALOC = ONE / DB
-                  END IF
-                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 10 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-   10                CONTINUE
-C
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1 ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-C
-               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
-C
-                  P21 = DDOT( M-K2, A( K2, MNK2 ), LDA, C( MNK2, L1 ),
-     $                        1 )
-                  DWORK( K2 ) = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ),
-     $                                1 )
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) )
-C
-                  SUMR = DDOT( M-K1+1, A( K2, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUMR + P21*B( L1, L1 ) )
-C
-                  CALL DLALN2( .FALSE., 2, 1, SMIN, B( L1, L1 ),
-     $                         A( K1, K1 ), LDA, ONE, ONE, VEC, 2, -SGN,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 20 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-   20                CONTINUE
-C
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1 ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K2, L1 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  P12  = DDOT( M-K1, A( K1, MNK1 ), LDA, C( MNK1, L2 ),
-     $                         1 )
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) +
-     $                                                 P12*B( L2, L1 ) )
-C
-                  DWORK( K1+M ) = DDOT( L1-1, C( K1, 1 ), LDC,
-     $                                  B( 1, L2 ), 1 )
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1+M ),
-     $                         1 )
-                  VEC( 2, 1 ) = C( K1, L2 ) - ( SUMR + P11*B( L1, L2 ) +
-     $                                                 P12*B( L2, L2 ) )
-C
-                  CALL DLALN2( .TRUE., 2, 1, SMIN, A( K1, K1 ),
-     $                         B( L1, L1 ), LDB, ONE, ONE, VEC, 2, -SGN,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 30 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-   30                CONTINUE
-C
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1 ), 1 )
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1+M ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
-C
-                  P21 = DDOT( M-K2, A( K2, MNK2 ), LDA, C( MNK2, L1 ),
-     $                        1 )
-                  P12 = DDOT( M-K2, A( K1, MNK2 ), LDA, C( MNK2, L2 ),
-     $                        1 )
-                  P22 = DDOT( M-K2, A( K2, MNK2 ), LDA, C( MNK2, L2 ),
-     $                        1 )
-C
-                  DWORK( K2 ) = DDOT( L1-1, C( K2, 1 ), LDC, B( 1, L1 ),
-     $                                1 )
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) +
-     $                                                 P12*B( L2, L1 ) )
-C
-                  DWORK( K1+M ) = DDOT( L1-1, C( K1, 1 ), LDC,
-     $                                  B( 1, L2 ), 1 )
-                  DWORK( K2+M ) = DDOT( L1-1, C( K2, 1 ), LDC,
-     $                                  B( 1, L2 ), 1 )
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1+M ),
-     $                         1 )
-                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUMR + P11*B( L1, L2 ) +
-     $                                                 P12*B( L2, L2 ) )
-C
-                  SUMR = DDOT( M-K1+1, A( K2, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUMR + P21*B( L1, L1 ) +
-     $                                                 P22*B( L2, L1 ) )
-C
-                  SUMR = DDOT( M-K1+1, A( K2, K1 ), LDA, DWORK( K1+M ),
-     $                         1 )
-                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUMR + P21*B( L1, L2 ) +
-     $                                                 P22*B( L2, L2 ) )
-C
-                  CALL SB04PX( .FALSE., .FALSE., ISGN, 2, 2,
-     $                         A( K1, K1 ), LDA, B( L1, L1 ), LDB, VEC,
-     $                         2, SCALOC, X, 2, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 40 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-   40                CONTINUE
-C
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1 ), 1 )
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1+M ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 1, 2 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( K2, L2 ) = X( 2, 2 )
-               END IF
-C
-   50       CONTINUE
-C
-   60    CONTINUE
-C
-      ELSE IF( .NOT.NOTRNA .AND. NOTRNB ) THEN
-C
-C        Solve     A'*X*B + ISGN*X = scale*C.
-C
-C        The (K,L)th block of X is determined starting from
-C        upper-left corner column by column by
-C
-C         A(K,K)'*X(K,L)*B(L,L) + ISGN*X(K,L) = C(K,L) - R(K,L)
-C
-C        where
-C                      K-1
-C           R(K,L) = { SUM [A(J,K)'*X(J,L)] } * B(L,L) +
-C                      J=1
-C                       K              L-1
-C                      SUM A(J,K)' * { SUM [X(J,I)*B(I,L)] }.
-C                      J=1             I=1
-C
-C        Start column loop (index = L)
-C        L1 (L2): column index of the first (last) row of X(K,L).
-C
-         LNEXT = 1
-C
-         DO 120 L = 1, N
-            IF( L.LT.LNEXT )
-     $         GO TO 120
-            L1 = L
-            IF( L.EQ.N ) THEN
-               L2 = L
-            ELSE
-               IF( B( L+1, L ).NE.ZERO ) THEN
-                  L2 = L + 1
-               ELSE
-                  L2 = L
-               END IF
-               LNEXT = L2 + 1
-            END IF
-C
-C           Start row loop (index = K)
-C           K1 (K2): row index of the first (last) row of X(K,L).
-C
-            KNEXT = 1
-C
-            DO 110 K = 1, M
-               IF( K.LT.KNEXT )
-     $            GO TO 110
-               K1 = K
-               IF( K.EQ.M ) THEN
-                  K2 = K
-               ELSE
-                  IF( A( K+1, K ).NE.ZERO ) THEN
-                     K2 = K + 1
-                  ELSE
-                     K2 = K
-                  END IF
-                  KNEXT = K2 + 1
-               END IF
-C
-               P11 = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
-               DWORK( K1 ) = DDOT( L1-1, C( K1, 1 ), LDC, B( 1, L1),
-     $                             1 )
-C
-               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  SUMR = DDOT( K1, A( 1, K1 ), 1, DWORK, 1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) )
-                  SCALOC = ONE
-C
-                  A11  = A( K1, K1 )*B( L1, L1 ) + SGN
-                  DA11 = ABS( A11 )
-                  IF( DA11.LE.SMIN ) THEN
-                     A11  = SMIN
-                     DA11 = SMIN
-                     INFO = 1
-                  END IF
-                  DB = ABS( VEC( 1, 1 ) )
-                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
-                     IF( DB.GT.BIGNUM*DA11 )
-     $                  SCALOC = ONE / DB
-                  END IF
-                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 70 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-   70                CONTINUE
-C
-                     CALL DSCAL( K1, SCALOC, DWORK, 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-C
-               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
-C
-                  P21 = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
-                  DWORK( K2 ) = DDOT( L1-1, C( K2, 1 ), LDC,
-     $                                B( 1, L1), 1 )
-                  SUMR = DDOT( K2, A( 1, K1 ), 1, DWORK, 1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) )
-C
-                  SUMR = DDOT( K2, A( 1, K2 ), 1, DWORK, 1 )
-                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUMR + P21*B( L1, L1 ) )
-C
-                  CALL DLALN2( .TRUE., 2, 1, SMIN, B( L1, L1 ),
-     $                         A( K1, K1 ), LDA, ONE, ONE, VEC, 2, -SGN,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 80 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-   80                CONTINUE
-C
-                     CALL DSCAL( K2, SCALOC, DWORK, 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K2, L1 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  P12  = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
-                  SUMR = DDOT( K1, A( 1, K1 ), 1, DWORK, 1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) +
-     $                                                 P12*B( L2, L1 ) )
-C
-                  DWORK( K1+M ) = DDOT( L1-1, C( K1, 1 ), LDC,
-     $                                  B( 1, L2 ), 1 )
-                  SUMR = DDOT( K1, A( 1, K1 ), 1, DWORK( M+1 ), 1 )
-                  VEC( 2, 1 ) = C( K1, L2 ) - ( SUMR + P11*B( L1, L2 ) +
-     $                                                 P12*B( L2, L2 ) )
-C
-                  CALL DLALN2( .TRUE., 2, 1, SMIN, A( K1, K1 ),
-     $                         B( L1, L1 ), LDB, ONE, ONE, VEC, 2, -SGN,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 90 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-   90                CONTINUE
-C
-                     CALL DSCAL( K1, SCALOC, DWORK, 1 )
-                     CALL DSCAL( K1, SCALOC, DWORK( M+1 ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
-C
-                  P21 = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
-                  P12 = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
-                  P22 = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )
-C
-                  DWORK( K2 ) = DDOT( L1-1, C( K2, 1 ), LDC,
-     $                                B( 1, L1), 1 )
-                  SUMR = DDOT( K2, A( 1, K1 ), 1, DWORK, 1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) +
-     $                                                 P12*B( L2, L1 ) )
-C
-                  SUMR = DDOT( K2, A( 1, K2 ), 1, DWORK, 1 )
-                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUMR + P21*B( L1, L1 ) +
-     $                                                 P22*B( L2, L1 ) )
-C
-                  DWORK( K1+M ) = DDOT( L1-1, C( K1, 1 ), LDC,
-     $                                  B( 1, L2 ), 1 )
-                  DWORK( K2+M ) = DDOT( L1-1, C( K2, 1 ), LDC,
-     $                                  B( 1, L2 ), 1 )
-                  SUMR = DDOT( K2, A( 1, K1 ), 1, DWORK( M+1 ), 1 )
-                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUMR + P11*B( L1, L2 ) +
-     $                                                 P12*B( L2, L2 ) )
-C
-                  SUMR = DDOT( K2, A( 1, K2 ), 1, DWORK( M+1 ), 1 )
-                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUMR + P21*B( L1, L2 ) +
-     $                                                 P22*B( L2, L2 ) )
-C
-                  CALL SB04PX( .TRUE., .FALSE., ISGN, 2, 2, A( K1, K1 ),
-     $                         LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,
-     $                         2, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 100 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-  100                CONTINUE
-C
-                     CALL DSCAL( K2, SCALOC, DWORK, 1 )
-                     CALL DSCAL( K2, SCALOC, DWORK( M+1 ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 1, 2 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( K2, L2 ) = X( 2, 2 )
-               END IF
-C
-  110       CONTINUE
-C
-  120    CONTINUE
-C
-      ELSE IF( .NOT.NOTRNA .AND. .NOT.NOTRNB ) THEN
-C
-C        Solve    A'*X*B' + ISGN*X = scale*C.
-C
-C        The (K,L)th block of X is determined starting from
-C        top-right corner column by column by
-C
-C           A(K,K)'*X(K,L)*B(L,L)' + ISGN*X(K,L) = C(K,L) - R(K,L)
-C
-C        where
-C                      K-1
-C           R(K,L) = { SUM [A(J,K)'*X(J,L)] } * B(L,L)' +
-C                      J=1
-C                       K               N
-C                      SUM A(J,K)' * { SUM [X(J,I)*B(L,I)'] }.
-C                      J=1            I=L+1
-C
-C        Start column loop (index = L)
-C        L1 (L2): column index of the first (last) row of X(K,L).
-C
-         LNEXT = N
-C
-         DO 180 L = N, 1, -1
-            IF( L.GT.LNEXT )
-     $         GO TO 180
-            L2 = L
-            IF( L.EQ.1 ) THEN
-               L1 = L
-            ELSE
-               IF( B( L, L-1 ).NE.ZERO ) THEN
-                  L1 = L - 1
-               ELSE
-                  L1 = L
-               END IF
-               LNEXT = L1 - 1
-            END IF
-C
-C           Start row loop (index = K)
-C           K1 (K2): row index of the first (last) row of X(K,L).
-C
-            KNEXT = 1
-C
-            DO 170 K = 1, M
-               IF( K.LT.KNEXT )
-     $            GO TO 170
-               K1 = K
-               IF( K.EQ.M ) THEN
-                  K2 = K
-               ELSE
-                  IF( A( K+1, K ).NE.ZERO ) THEN
-                     K2 = K + 1
-                  ELSE
-                     K2 = K
-                  END IF
-                  KNEXT = K2 + 1
-               END IF
-C
-               MNL1 = MIN( L1+1, N )
-               MNL2 = MIN( L2+1, N )
-               P11  = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L1 ), 1 )
-               DWORK( K1 ) = DDOT( N-L2, C( K1, MNL2 ), LDC,
-     $                             B( L1, MNL2 ), LDB )
-C
-               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
-                  SUMR = DDOT( K1, A( 1, K1 ), 1, DWORK, 1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) )
-                  SCALOC = ONE
-C
-                  A11  = A( K1, K1 )*B( L1, L1 ) + SGN
-                  DA11 = ABS( A11 )
-                  IF( DA11.LE.SMIN ) THEN
-                     A11  = SMIN
-                     DA11 = SMIN
-                     INFO = 1
-                  END IF
-                  DB = ABS( VEC( 1, 1 ) )
-                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
-                     IF( DB.GT.BIGNUM*DA11 )
-     $                  SCALOC = ONE / DB
-                  END IF
-                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 130 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-  130                CONTINUE
-C
-                     CALL DSCAL( K1, SCALOC, DWORK, 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-C
-               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
-C
-                  P21 = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
-                  DWORK( K2 ) = DDOT( N-L1, C( K2, MNL1 ), LDC,
-     $                                B( L1, MNL1 ), LDB )
-                  SUMR = DDOT( K2, A( 1, K1 ), 1, DWORK, 1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) )
-C
-                  SUMR = DDOT( K2, A( 1, K2 ), 1, DWORK, 1 )
-                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUMR + P21*B( L1, L1 ) )
-C
-                  CALL DLALN2( .TRUE., 2, 1, SMIN, B( L1, L1 ),
-     $                         A( K1, K1 ), LDA, ONE, ONE, VEC, 2, -SGN,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 140 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-  140                CONTINUE
-C
-                     CALL DSCAL( K2, SCALOC, DWORK, 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K2, L1 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  P12  = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
-                  SUMR = DDOT( K1, A( 1, K1 ), 1, DWORK, 1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) +
-     $                                                 P12*B( L1, L2 ) )
-C
-                  DWORK( K1+M ) = DDOT( N-L2, C( K1, MNL2 ), LDC,
-     $                                  B( L2, MNL2 ), LDB )
-                  SUMR = DDOT( K1, A( 1, K1 ), 1, DWORK( M+1 ), 1 )
-                  VEC( 2, 1 ) = C( K1, L2 ) - ( SUMR + P11*B( L2, L1 ) +
-     $                                                 P12*B( L2, L2 ) )
-C
-                  CALL DLALN2( .FALSE., 2, 1, SMIN, A( K1, K1 ),
-     $                         B( L1, L1 ), LDB, ONE, ONE, VEC, 2, -SGN,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 150 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-  150                CONTINUE
-C
-                     CALL DSCAL( K1, SCALOC, DWORK, 1 )
-                     CALL DSCAL( K1, SCALOC, DWORK(M+1), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
-C
-                  P21 = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L1 ), 1 )
-                  P12 = DDOT( K1-1, A( 1, K1 ), 1, C( 1, L2 ), 1 )
-                  P22 = DDOT( K1-1, A( 1, K2 ), 1, C( 1, L2 ), 1 )
-C
-                  DWORK( K2 ) = DDOT( N-L2, C( K2, MNL2 ), LDC,
-     $                                B( L1, MNL2 ), LDB )
-                  SUMR = DDOT( K2, A( 1, K1 ), 1, DWORK, 1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) +
-     $                                                 P12*B( L1, L2 ) )
-C
-                  SUMR = DDOT( K2, A( 1, K2 ), 1, DWORK, 1 )
-                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUMR + P21*B( L1, L1 ) +
-     $                                                 P22*B( L1, L2 ) )
-C
-                  DWORK( K1+M ) = DDOT( N-L2, C( K1, MNL2 ), LDC,
-     $                                  B( L2, MNL2 ), LDB )
-                  DWORK( K2+M ) = DDOT( N-L2, C( K2, MNL2 ), LDC,
-     $                                  B( L2, MNL2 ), LDB )
-                  SUMR = DDOT( K2, A( 1, K1 ), 1, DWORK( M+1 ), 1 )
-                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUMR + P11*B( L2, L1 ) +
-     $                                                 P12*B( L2, L2 ) )
-C
-                  SUMR = DDOT( K2, A( 1, K2 ), 1, DWORK( M+1 ), 1 )
-                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUMR + P21*B( L2, L1 ) +
-     $                                                 P22*B( L2, L2 ) )
-C
-                  CALL SB04PX( .TRUE., .TRUE., ISGN, 2, 2, A( K1, K1 ),
-     $                         LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,
-     $                         2, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 160 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-  160                CONTINUE
-C
-                     CALL DSCAL( K2, SCALOC, DWORK, 1 )
-                     CALL DSCAL( K2, SCALOC, DWORK(M+1), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 1, 2 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( K2, L2 ) = X( 2, 2 )
-               END IF
-C
-  170       CONTINUE
-C
-  180    CONTINUE
-C
-      ELSE
-C
-C        Solve    A*X*B' + ISGN*X = scale*C.
-C
-C        The (K,L)th block of X is determined starting from
-C        bottom-right corner column by column by
-C
-C            A(K,K)*X(K,L)*B(L,L)' + ISGN*X(K,L) = C(K,L) - R(K,L)
-C
-C        where
-C                       M
-C           R(K,L) = { SUM [A(K,J)*X(J,L)] } * B(L,L)' +
-C                     J=K+1
-C                       M              N
-C                      SUM { A(K,J) * SUM [X(J,I)*B(L,I)'] }.
-C                      J=K           I=L+1
-C
-C        Start column loop (index = L)
-C        L1 (L2): column index of the first (last) row of X(K,L).
-C
-         LNEXT = N
-C
-         DO 240 L = N, 1, -1
-            IF( L.GT.LNEXT )
-     $         GO TO 240
-            L2 = L
-            IF( L.EQ.1 ) THEN
-               L1 = L
-            ELSE
-               IF( B( L, L-1 ).NE.ZERO ) THEN
-                  L1 = L - 1
-               ELSE
-                  L1 = L
-               END IF
-               LNEXT = L1 - 1
-            END IF
-C
-C           Start row loop (index = K)
-C           K1 (K2): row index of the first (last) row of X(K,L).
-C
-            KNEXT = M
-C
-            DO 230 K = M, 1, -1
-               IF( K.GT.KNEXT )
-     $            GO TO 230
-               K2 = K
-               IF( K.EQ.1 ) THEN
-                  K1 = K
-               ELSE
-                  IF( A( K, K-1 ).NE.ZERO ) THEN
-                     K1 = K - 1
-                  ELSE
-                     K1 = K
-                  END IF
-                  KNEXT = K1 - 1
-               END IF
-C
-               MNK1 = MIN( K1+1, M )
-               MNK2 = MIN( K2+1, M )
-               MNL1 = MIN( L1+1, N )
-               MNL2 = MIN( L2+1, N )
-               P11  = DDOT( M-K2, A( K1, MNK2 ), LDA, C( MNK2, L1 ), 1 )
-               DWORK( K1 ) = DDOT( N-L2, C( K1, MNL2 ), LDC,
-     $                             B( L1, MNL2 ), LDB )
-C
-               IF( L1.EQ.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) )
-                  SCALOC = ONE
-C
-                  A11  = A( K1, K1 )*B( L1, L1 ) + SGN
-                  DA11 = ABS( A11 )
-                  IF( DA11.LE.SMIN ) THEN
-                     A11  = SMIN
-                     DA11 = SMIN
-                     INFO = 1
-                  END IF
-                  DB = ABS( VEC( 1, 1 ) )
-                  IF( DA11.LT.ONE .AND. DB.GT.ONE ) THEN
-                     IF( DB.GT.BIGNUM*DA11 )
-     $                  SCALOC = ONE / DB
-                  END IF
-                  X( 1, 1 ) = ( VEC( 1, 1 )*SCALOC ) / A11
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 190 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-  190                CONTINUE
-C
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1 ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-C
-               ELSE IF( L1.EQ.L2 .AND. K1.NE.K2 ) THEN
-C
-                  P21 = DDOT( M-K2, A( K2, MNK2 ), LDA, C( MNK2, L1 ),
-     $                        1 )
-                  DWORK( K2 ) = DDOT( N-L1, C( K2, MNL1 ), LDC,
-     $                                B( L1, MNL1 ), LDB )
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) )
-C
-                  SUMR = DDOT( M-K1+1, A( K2, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUMR + P21*B( L1, L1 ) )
-C
-                  CALL DLALN2( .FALSE., 2, 1, SMIN, B( L1, L1 ),
-     $                         A( K1, K1 ), LDA, ONE, ONE, VEC, 2, -SGN,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 200 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-  200                CONTINUE
-C
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1 ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K2, L1 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.EQ.K2 ) THEN
-C
-                  P12  = DDOT( M-K1, A( K1, MNK1 ), LDA, C( MNK1, L2 ),
-     $                         1 )
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) +
-     $                                                 P12*B( L1, L2 ) )
-C
-                  DWORK( K1+M ) = DDOT( N-L2, C( K1, MNL2 ), LDC,
-     $                                  B( L2, MNL2 ), LDB )
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1+M ),
-     $                         1 )
-                  VEC( 2, 1 ) = C( K1, L2 ) - ( SUMR + P11*B( L2, L1 ) +
-     $                                                 P12*B( L2, L2 ) )
-C
-                  CALL DLALN2( .FALSE., 2, 1, SMIN, A( K1, K1 ),
-     $                         B( L1, L1 ), LDB, ONE, ONE, VEC, 2, -SGN,
-     $                         ZERO, X, 2, SCALOC, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 210 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-  210                CONTINUE
-C
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1 ), 1 )
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1+M ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 2, 1 )
-C
-               ELSE IF( L1.NE.L2 .AND. K1.NE.K2 ) THEN
-C
-                  P21 = DDOT( M-K2, A( K2, MNK2 ), LDA, C( MNK2, L1 ),
-     $                        1 )
-                  P12 = DDOT( M-K2, A( K1, MNK2 ), LDA, C( MNK2, L2 ),
-     $                        1 )
-                  P22 = DDOT( M-K2, A( K2, MNK2 ), LDA, C( MNK2, L2 ),
-     $                        1 )
-C
-                  DWORK( K2 ) = DDOT( N-L2, C( K2, MNL2 ), LDC,
-     $                                B( L1, MNL2 ), LDB )
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 1, 1 ) = C( K1, L1 ) - ( SUMR + P11*B( L1, L1 ) +
-     $                                                 P12*B( L1, L2 ) )
-C
-                  SUMR = DDOT( M-K1+1, A( K2, K1 ), LDA, DWORK( K1 ),
-     $                         1 )
-                  VEC( 2, 1 ) = C( K2, L1 ) - ( SUMR + P21*B( L1, L1 ) +
-     $                                                 P22*B( L1, L2 ) )
-C
-                  DWORK( K1+M ) = DDOT( N-L2, C( K1, MNL2 ), LDC,
-     $                                  B( L2, MNL2 ), LDB )
-                  DWORK( K2+M ) = DDOT( N-L2, C( K2, MNL2 ), LDC,
-     $                                  B( L2, MNL2 ), LDB )
-                  SUMR = DDOT( M-K1+1, A( K1, K1 ), LDA, DWORK( K1+M ),
-     $                         1 )
-                  VEC( 1, 2 ) = C( K1, L2 ) - ( SUMR + P11*B( L2, L1 ) +
-     $                                                 P12*B( L2, L2 ) )
-C
-                  SUMR = DDOT( M-K1+1, A( K2, K1 ), LDA, DWORK( K1+M ),
-     $                         1 )
-                  VEC( 2, 2 ) = C( K2, L2 ) - ( SUMR + P21*B( L2, L1 ) +
-     $                                                 P22*B( L2, L2 ) )
-C
-                  CALL SB04PX( .FALSE., .TRUE., ISGN, 2, 2, A( K1, K1 ),
-     $                         LDA, B( L1, L1 ), LDB, VEC, 2, SCALOC, X,
-     $                         2, XNORM, IERR )
-                  IF( IERR.NE.0 )
-     $               INFO = 1
-C
-                  IF( SCALOC.NE.ONE ) THEN
-C
-                     DO 220 J = 1, N
-                        CALL DSCAL( M, SCALOC, C( 1, J ), 1 )
-  220                CONTINUE
-C
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1 ), 1 )
-                     CALL DSCAL( M-K1+1, SCALOC, DWORK( K1+M ), 1 )
-                     SCALE = SCALE*SCALOC
-                  END IF
-                  C( K1, L1 ) = X( 1, 1 )
-                  C( K1, L2 ) = X( 1, 2 )
-                  C( K2, L1 ) = X( 2, 1 )
-                  C( K2, L2 ) = X( 2, 2 )
-               END IF
-C
-  230       CONTINUE
-C
-  240    CONTINUE
-C
-      END IF
-C
-      RETURN
-C *** Last line of SB04PY ***
-      END
--- a/extra/control-devel/src/SB08CD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,355 +0,0 @@
-      SUBROUTINE SB08CD( DICO, N, M, P, A, LDA, B, LDB, C, LDC, D, LDD,
-     $                   NQ, NR, BR, LDBR, DR, LDDR, TOL, DWORK, LDWORK,
-     $                   IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To construct, for a given system G = (A,B,C,D), an output
-C     injection matrix H, an orthogonal transformation matrix Z, and a
-C     gain matrix V, such that the systems
-C
-C          Q = (Z'*(A+H*C)*Z, Z'*(B+H*D), V*C*Z, V*D)
-C     and
-C          R = (Z'*(A+H*C)*Z, Z'*H, V*C*Z, V)
-C
-C     provide a stable left coprime factorization of G in the form
-C                   -1
-C              G = R  * Q,
-C
-C     where G, Q and R are the corresponding transfer-function matrices
-C     and the denominator R is co-inner, that is, R(s)*R'(-s) = I in
-C     the continuous-time case, or R(z)*R'(1/z) = I in the discrete-time
-C     case. The Z matrix is not explicitly computed.
-C
-C     Note: G must have no observable poles on the imaginary axis
-C     for a continuous-time system, or on the unit circle for a
-C     discrete-time system. If the given state-space representation
-C     is not detectable, the undetectable part of the original
-C     system is automatically deflated and the order of the systems
-C     Q and R is accordingly reduced.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The dimension of the state vector, i.e. the order of the
-C             matrix A, and also the number of rows of the matrices B
-C             and BR, and the number of columns of the matrix C.
-C             N >= 0.
-C
-C     M       (input) INTEGER
-C             The dimension of input vector, i.e. the number of columns
-C             of the matrices B and D.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The dimension of output vector, i.e. the number of rows
-C             of the matrices C, D and DR, and the number of columns
-C             of the matrices BR and DR.  P >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A. The matrix A must not
-C             have observable eigenvalues on the imaginary axis, if
-C             DICO = 'C', or on the unit circle, if DICO = 'D'.
-C             On exit, the leading NQ-by-NQ part of this array contains
-C             the leading NQ-by-NQ part of the matrix Z'*(A+H*C)*Z, the
-C             state dynamics matrix of the numerator factor Q, in a
-C             real Schur form. The leading NR-by-NR part of this matrix
-C             represents the state dynamics matrix of a minimal
-C             realization of the denominator factor R.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension
-C             (LDB,MAX(M,P))
-C             On entry, the leading N-by-M part of this array must
-C             contain the input/state matrix.
-C             On exit, the leading NQ-by-M part of this array contains
-C             the leading NQ-by-M part of the matrix Z'*(B+H*D), the
-C             input/state matrix of the numerator factor Q.
-C             The remaining part of this array is needed as workspace.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the state/output matrix C.
-C             On exit, the leading P-by-NQ part of this array contains
-C             the leading P-by-NQ part of the matrix V*C*Z, the
-C             state/output matrix of the numerator factor Q.
-C             The first NR columns of this array represent the
-C             state/output matrix of a minimal realization of the
-C             denominator factor R.
-C             The remaining part of this array is needed as workspace.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.
-C             LDC >= MAX(1,M,P), if N > 0.
-C             LDC >= 1,          if N = 0.
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension
-C             (LDD,MAX(M,P))
-C             On entry, the leading P-by-M part of this array must
-C             contain the input/output matrix.
-C             On exit, the leading P-by-M part of this array contains
-C             the matrix V*D representing the input/output matrix
-C             of the numerator factor Q.
-C             The remaining part of this array is needed as workspace.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,M,P).
-C
-C     NQ      (output) INTEGER
-C             The order of the resulting factors Q and R.
-C             Generally, NQ = N - NS, where NS is the number of
-C             unobservable eigenvalues outside the stability region.
-C
-C     NR      (output) INTEGER
-C             The order of the minimal realization of the factor R.
-C             Generally, NR is the number of observable eigenvalues
-C             of A outside the stability region (the number of modified
-C             eigenvalues).
-C
-C     BR      (output) DOUBLE PRECISION array, dimension (LDBR,P)
-C             The leading NQ-by-P part of this array contains the
-C             leading NQ-by-P part of the output injection matrix
-C             Z'*H, which reflects the eigenvalues of A lying outside
-C             the stable region to values which are symmetric with
-C             respect to the imaginary axis (if DICO = 'C') or the unit
-C             circle (if DICO = 'D'). The first NR rows of this matrix
-C             form the input/state matrix of a minimal realization of
-C             the denominator factor R.
-C
-C     LDBR    INTEGER
-C             The leading dimension of array BR.  LDBR >= MAX(1,N).
-C
-C     DR      (output) DOUBLE PRECISION array, dimension (LDDR,P)
-C             The leading P-by-P part of this array contains the lower
-C             triangular matrix V representing the input/output matrix
-C             of the denominator factor R.
-C
-C     LDDR    INTEGER
-C             The leading dimension of array DR.  LDDR >= MAX(1,P).
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The absolute tolerance level below which the elements of
-C             C are considered zero (used for observability tests).
-C             If the user sets TOL <= 0, then an implicitly computed,
-C             default tolerance, defined by  TOLDEF = N*EPS*NORM(C),
-C             is used instead, where EPS is the machine precision
-C             (see LAPACK Library routine DLAMCH) and NORM(C) denotes
-C             the infinity-norm of C.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The dimension of working array DWORK.
-C             LDWORK >= MAX( 1, P*N + MAX( N*(N+5),P*(P+2),4*P,4*M ) ).
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = K:  K violations of the numerical stability condition
-C                   NORM(H) <= 10*NORM(A)/NORM(C) occured during the
-C                   assignment of eigenvalues.
-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 reduction of A to a real Schur form failed;
-C             = 2:  a failure was detected during the ordering of the
-C                   real Schur form of A, or in the iterative process
-C                   for reordering the eigenvalues of Z'*(A + H*C)*Z
-C                   along the diagonal;
-C             = 3:  if DICO = 'C' and the matrix A has an observable
-C                   eigenvalue on the imaginary axis, or DICO = 'D' and
-C                   A has an observable eigenvalue on the unit circle.
-C
-C     METHOD
-C
-C     The subroutine uses the right coprime factorization algorithm with
-C     inner denominator of [1] applied to G'.
-C
-C     REFERENCES
-C
-C     [1] Varga A.
-C         A Schur method for computing coprime factorizations with
-C         inner denominators and applications in model reduction.
-C         Proc. ACC'93, San Francisco, CA, pp. 2130-2131, 1993.
-C
-C     NUMERICAL ASPECTS
-C                                            3
-C     The algorithm requires no more than 14N  floating point
-C     operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, July 1998.
-C     Based on the RASP routine LCFID.
-C
-C     REVISIONS
-C
-C     Nov. 1998, V. Sima, Research Institute for Informatics, Bucharest.
-C     Dec. 1998, V. Sima, Katholieke Univ. Leuven, Leuven.
-C     May  2003, A. Varga, DLR Oberpfaffenhofen.
-C     Nov  2003, A. Varga, DLR Oberpfaffenhofen.
-C
-C     KEYWORDS
-C
-C     Coprime factorization, eigenvalue, eigenvalue assignment,
-C     feedback control, pole placement, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO
-      INTEGER           INFO, IWARN, LDA, LDB, LDBR, LDC, LDD, LDDR,
-     $                  LDWORK, M, N, NQ, NR, P
-      DOUBLE PRECISION  TOL
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), BR(LDBR,*), C(LDC,*),
-     $                  D(LDD,*), DR(LDDR,*), DWORK(*)
-C     .. Local Scalars ..
-      INTEGER           I, KBR, KW
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External subroutines ..
-      EXTERNAL          AB07MD, DLASET, DSWAP, MA02AD, MA02BD, SB08DD,
-     $                  TB01XD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, MAX, MIN
-C     .. Executable Statements ..
-C
-      IWARN = 0
-      INFO  = 0
-C
-C     Check the scalar input parameters.
-C
-      IF( .NOT.LSAME( DICO, 'C' ) .AND.
-     $    .NOT.LSAME( DICO, 'D' ) ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( LDC.LT.1 .OR. ( N.GT.0 .AND. LDC.LT.MAX( M, P ) ) )
-     $      THEN
-         INFO = -10
-      ELSE IF( LDD.LT.MAX( 1, M, P ) ) THEN
-         INFO = -12
-      ELSE IF( LDBR.LT.MAX( 1, N ) ) THEN
-         INFO = -16
-      ELSE IF( LDDR.LT.MAX( 1, P ) ) THEN
-         INFO = -18
-      ELSE IF( LDWORK.LT.MAX( 1, P*N + MAX( N*(N+5), P*(P+2), 4*P,
-     $                        4*M ) ) ) THEN
-         INFO = -21
-      END IF
-      IF( INFO.NE.0 )THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB08CD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, P ).EQ.0 ) THEN
-         NQ = 0
-         NR = 0
-         DWORK(1) = ONE
-         CALL DLASET( 'Full', P, P, ZERO, ONE, DR, LDDR )
-         RETURN
-      END IF
-C
-C     Compute the dual system G' = (A',C',B',D').
-C
-      CALL AB07MD( 'D', N, M, P, A, LDA, B, LDB, C, LDC, D, LDD,
-     $             INFO )
-C
-C     Compute the right coprime factorization with inner
-C     denominator of G'.
-C
-C     Workspace needed:      P*N;
-C     Additional workspace:  need  MAX( N*(N+5), P*(P+2), 4*P, 4*M );
-C                            prefer larger.
-C
-      KBR = 1
-      KW  = KBR + P*N
-      CALL SB08DD( DICO, N, P, M, A, LDA, B, LDB, C, LDC, D, LDD,
-     $             NQ, NR, DWORK(KBR), P, DR, LDDR, TOL, DWORK(KW),
-     $             LDWORK-KW+1, IWARN, INFO )
-      IF( INFO.EQ.0 ) THEN
-C
-C        Determine the elements of the left coprime factorization from
-C        those of the computed right coprime factorization and make the
-C        state-matrix upper real Schur.
-C
-         CALL TB01XD( 'D', NQ, P, M, MAX( 0, NQ-1 ), MAX( 0, NQ-1 ),
-     $                A, LDA, B, LDB, C, LDC, D, LDD, INFO )
-C
-         CALL MA02AD( 'Full', P, NQ, DWORK(KBR), P, BR, LDBR )
-         CALL MA02BD( 'Left', NQ, P, BR, LDBR )
-C
-         DO 10 I = 2, P
-            CALL DSWAP( I-1, DR(I,1), LDDR, DR(1,I), 1 )
-   10    CONTINUE
-C
-      END IF
-C
-      DWORK(1) = DWORK(KW) + DBLE( KW-1 )
-C
-      RETURN
-C *** Last line of SB08CD ***
-      END
--- a/extra/control-devel/src/SB08DD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,583 +0,0 @@
-      SUBROUTINE SB08DD( DICO, N, M, P, A, LDA, B, LDB, C, LDC, D, LDD,
-     $                   NQ, NR, CR, LDCR, DR, LDDR, TOL, DWORK, LDWORK,
-     $                   IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To construct, for a given system G = (A,B,C,D), a feedback matrix
-C     F, an orthogonal transformation matrix Z, and a gain matrix V,
-C     such that the systems
-C
-C          Q = (Z'*(A+B*F)*Z, Z'*B*V, (C+D*F)*Z, D*V)
-C     and
-C          R = (Z'*(A+B*F)*Z, Z'*B*V, F*Z, V)
-C
-C     provide a stable right coprime factorization of G in the form
-C                       -1
-C              G = Q * R  ,
-C
-C     where G, Q and R are the corresponding transfer-function matrices
-C     and the denominator R is inner, that is, R'(-s)*R(s) = I in the
-C     continuous-time case, or R'(1/z)*R(z) = I in the discrete-time
-C     case. The Z matrix is not explicitly computed.
-C
-C     Note: G must have no controllable poles on the imaginary axis
-C     for a continuous-time system, or on the unit circle for a
-C     discrete-time system. If the given state-space representation
-C     is not stabilizable, the unstabilizable part of the original
-C     system is automatically deflated and the order of the systems
-C     Q and R is accordingly reduced.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The dimension of the state vector, i.e. the order of the
-C             matrix A, and also the number of rows of the matrix B and
-C             the number of columns of the matrices C and CR.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The dimension of input vector, i.e. the number of columns
-C             of the matrices B, D and DR and the number of rows of the
-C             matrices CR and DR.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The dimension of output vector, i.e. the number of rows
-C             of the matrices C and D.  P >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A. The matrix A must not
-C             have controllable eigenvalues on the imaginary axis, if
-C             DICO = 'C', or on the unit circle, if DICO = 'D'.
-C             On exit, the leading NQ-by-NQ part of this array contains
-C             the leading NQ-by-NQ part of the matrix Z'*(A+B*F)*Z, the
-C             state dynamics matrix of the numerator factor Q, in a
-C             real Schur form. The trailing NR-by-NR part of this matrix
-C             represents the state dynamics matrix of a minimal
-C             realization of the denominator factor R.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input/state matrix.
-C             On exit, the leading NQ-by-M part of this array contains
-C             the leading NQ-by-M part of the matrix Z'*B*V, the
-C             input/state matrix of the numerator factor Q. The last
-C             NR rows of this matrix form the input/state matrix of
-C             a minimal realization of the denominator factor R.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the state/output matrix C.
-C             On exit, the leading P-by-NQ part of this array contains
-C             the leading P-by-NQ part of the matrix (C+D*F)*Z,
-C             the state/output matrix of the numerator factor Q.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the input/output matrix.
-C             On exit, the leading P-by-M part of this array contains
-C             the matrix D*V representing the input/output matrix
-C             of the numerator factor Q.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     NQ      (output) INTEGER
-C             The order of the resulting factors Q and R.
-C             Generally, NQ = N - NS, where NS is the number of
-C             uncontrollable eigenvalues outside the stability region.
-C
-C     NR      (output) INTEGER
-C             The order of the minimal realization of the factor R.
-C             Generally, NR is the number of controllable eigenvalues
-C             of A outside the stability region (the number of modified
-C             eigenvalues).
-C
-C     CR      (output) DOUBLE PRECISION array, dimension (LDCR,N)
-C             The leading M-by-NQ part of this array contains the
-C             leading M-by-NQ part of the feedback matrix F*Z, which
-C             reflects the eigenvalues of A lying outside the stable
-C             region to values which are symmetric with respect to the
-C             imaginary axis (if DICO = 'C') or the unit circle (if
-C             DICO = 'D').  The last NR columns of this matrix form the
-C             state/output matrix of a minimal realization of the
-C             denominator factor R.
-C
-C     LDCR    INTEGER
-C             The leading dimension of array CR.  LDCR >= MAX(1,M).
-C
-C     DR      (output) DOUBLE PRECISION array, dimension (LDDR,M)
-C             The leading M-by-M part of this array contains the upper
-C             triangular matrix V of order M representing the
-C             input/output matrix of the denominator factor R.
-C
-C     LDDR    INTEGER
-C             The leading dimension of array DR.  LDDR >= MAX(1,M).
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The absolute tolerance level below which the elements of
-C             B are considered zero (used for controllability tests).
-C             If the user sets TOL <= 0, then an implicitly computed,
-C             default tolerance, defined by  TOLDEF = N*EPS*NORM(B),
-C             is used instead, where EPS is the machine precision
-C             (see LAPACK Library routine DLAMCH) and NORM(B) denotes
-C             the 1-norm of B.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The dimension of working array DWORK.
-C             LDWORK >= MAX( 1, N*(N+5), M*(M+2), 4*M, 4*P ).
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = K:  K violations of the numerical stability condition
-C                   NORM(F) <= 10*NORM(A)/NORM(B) occured during the
-C                   assignment of eigenvalues.
-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 reduction of A to a real Schur form failed;
-C             = 2:  a failure was detected during the ordering of the
-C                   real Schur form of A, or in the iterative process
-C                   for reordering the eigenvalues of Z'*(A + B*F)*Z
-C                   along the diagonal;
-C             = 3:  if DICO = 'C' and the matrix A has a controllable
-C                   eigenvalue on the imaginary axis, or DICO = 'D'
-C                   and A has a controllable eigenvalue on the unit
-C                   circle.
-C
-C     METHOD
-C
-C     The subroutine is based on the factorization algorithm of [1].
-C
-C     REFERENCES
-C
-C     [1] Varga A.
-C         A Schur method for computing coprime factorizations with inner
-C         denominators and applications in model reduction.
-C         Proc. ACC'93, San Francisco, CA, pp. 2130-2131, 1993.
-C
-C     NUMERICAL ASPECTS
-C                                            3
-C     The algorithm requires no more than 14N  floating point
-C     operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, July 1998.
-C     Based on the RASP routine RCFID.
-C
-C     REVISIONS
-C
-C     Nov. 1998, V. Sima, Research Institute for Informatics, Bucharest.
-C     Dec. 1998, V. Sima, Katholieke Univ. Leuven, Leuven.
-C     Feb. 1999, May 2003, A. Varga, DLR Oberpfaffenhofen.
-C
-C     KEYWORDS
-C
-C     Coprime factorization, eigenvalue, eigenvalue assignment,
-C     feedback control, pole placement, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, TEN, ZERO
-      PARAMETER         ( ONE = 1.0D0, TEN = 1.0D1, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO
-      INTEGER           INFO, IWARN, LDA, LDB, LDC, LDCR, LDD, LDDR,
-     $                  LDWORK, M, N, NQ, NR, P
-      DOUBLE PRECISION  TOL
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), CR(LDCR,*),
-     $                  D(LDD,*), DR(LDDR,*), DWORK(*)
-C     .. Local Scalars ..
-      LOGICAL           DISCR
-      INTEGER           I, IB, IB1, J, K, KFI, KV, KW, KWI, KWR, KZ, L,
-     $                  L1, NB, NCUR, NFP, NLOW, NSUP
-      DOUBLE PRECISION  ALPHA, BNORM, CS, PR, RMAX, SM, SN, TOLER,
-     $                  WRKOPT, X, Y
-C     .. Local Arrays ..
-      DOUBLE PRECISION  Z(4,4)
-C     .. External Functions ..
-      DOUBLE PRECISION  DLAMCH, DLANGE
-      LOGICAL           LSAME
-      EXTERNAL          DLAMCH, DLANGE, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DGEMM, DLACPY, DLAEXC, DLANV2, DLASET, DROT,
-     $                  DTRMM, DTRMV, SB01FY, TB01LD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, MAX, MIN
-C     .. Executable Statements ..
-C
-      DISCR = LSAME( DICO, 'D' )
-      IWARN = 0
-      INFO  = 0
-C
-C     Check the scalar input parameters.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -10
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -12
-      ELSE IF( LDCR.LT.MAX( 1, M ) ) THEN
-         INFO = -16
-      ELSE IF( LDDR.LT.MAX( 1, M ) ) THEN
-         INFO = -18
-      ELSE IF( LDWORK.LT.MAX( 1, N*(N+5), M*(M+2), 4*M, 4*P ) ) THEN
-         INFO = -21
-      END IF
-      IF( INFO.NE.0 )THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB08DD', -INFO )
-         RETURN
-      END IF
-C
-C     Set DR = I and quick return if possible.
-C
-      NR = 0
-      IF( MIN( M, P ).GT.0 )
-     $   CALL DLASET( 'Full', M, M, ZERO, ONE, DR, LDDR )
-      IF( MIN( N, M ).EQ.0 ) THEN
-         NQ = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Set F = 0 in the array CR.
-C
-      CALL DLASET( 'Full', M, N, ZERO, ZERO, CR, LDCR )
-C
-C     Compute the norm of B and set the default tolerance if necessary.
-C
-      BNORM = DLANGE( '1-norm', N, M, B, LDB, DWORK )
-      TOLER = TOL
-      IF( TOLER.LE.ZERO )
-     $   TOLER = DBLE( N ) * BNORM * DLAMCH( 'Epsilon' )
-      IF( BNORM.LE.TOLER ) THEN
-         NQ = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Compute the bound for the numerical stability condition.
-C
-      RMAX = TEN * DLANGE( '1-norm', N, N, A, LDA, DWORK ) / BNORM
-C
-C     Allocate working storage.
-C
-      KZ  = 1
-      KWR = KZ  + N*N
-      KWI = KWR + N
-      KW  = KWI + N
-C
-C     Reduce A to an ordered real Schur form using an orthogonal
-C     similarity transformation A <- Z'*A*Z and accumulate the
-C     transformations in Z.  The separation of spectrum of A is
-C     performed such that the leading NFP-by-NFP submatrix of A
-C     corresponds to the "stable" eigenvalues which will be not
-C     modified. The bottom (N-NFP)-by-(N-NFP) diagonal block of A
-C     corresponds to the "unstable" eigenvalues to be modified.
-C     Apply the transformation to B and C: B <- Z'*B and C <- C*Z.
-C
-C     Workspace needed:      N*(N+2);
-C     Additional workspace:  need   3*N;
-C                            prefer larger.
-C
-      IF( DISCR ) THEN
-         ALPHA = ONE
-      ELSE
-         ALPHA = ZERO
-      END IF
-      CALL TB01LD( DICO, 'Stable', 'General', N, M, P, ALPHA, A, LDA,
-     $             B, LDB, C, LDC, NFP, DWORK(KZ), N, DWORK(KWR),
-     $             DWORK(KWI), DWORK(KW), LDWORK-KW+1, INFO )
-      IF( INFO.NE.0 )
-     $    RETURN
-C
-      WRKOPT = DWORK(KW) + DBLE( KW-1 )
-C
-C     Perform the pole assignment if there exist "unstable" eigenvalues.
-C
-      NQ = N
-      IF( NFP.LT.N ) THEN
-         KV  = 1
-         KFI = KV  + M*M
-         KW  = KFI + 2*M
-C
-C        Set the limits for the bottom diagonal block.
-C
-         NLOW = NFP + 1
-         NSUP = N
-C
-C        WHILE (NLOW <= NSUP) DO
-   10    IF( NLOW.LE.NSUP ) THEN
-C
-C           Main loop for assigning one or two poles.
-C
-C           Determine the dimension of the last block.
-C
-            IB = 1
-            IF( NLOW.LT.NSUP ) THEN
-               IF( A(NSUP,NSUP-1).NE.ZERO ) IB = 2
-            END IF
-            L = NSUP - IB + 1
-C
-C           Check the controllability of the last block.
-C
-            IF( DLANGE( '1-norm', IB, M, B(L,1), LDB, DWORK(KW) )
-     $            .LE.TOLER ) THEN
-C
-C              Deflate the uncontrollable block and resume the main
-C              loop.
-C
-               NSUP = NSUP - IB
-            ELSE
-C
-C              Determine the M-by-IB feedback matrix FI which assigns
-C              the selected IB poles for the pair
-C              ( A(L:L+IB-1,L:L+IB-1), B(L:L+IB-1,1:M) ).
-C
-C              Workspace needed: M*(M+2).
-C
-               CALL SB01FY( DISCR, IB, M, A(L,L), LDA, B(L,1), LDB,
-     $                      DWORK(KFI), M, DWORK(KV), M, INFO )
-               IF( INFO.EQ.2 ) THEN
-                  INFO = 3
-                  RETURN
-               END IF
-C
-C              Check for possible numerical instability.
-C
-               IF( DLANGE( '1-norm', M, IB, DWORK(KFI), M, DWORK(KW) )
-     $               .GT.RMAX ) IWARN = IWARN + 1
-C
-C              Update the state matrix A <-- A + B*[0 FI].
-C
-               CALL DGEMM( 'NoTranspose', 'NoTranspose', NSUP, IB, M,
-     $                     ONE, B, LDB, DWORK(KFI), M, ONE, A(1,L),
-     $                     LDA )
-C
-C              Update the feedback matrix F <-- F + V*[0 FI] in CR.
-C
-               IF( DISCR )
-     $            CALL DTRMM( 'Left', 'Upper', 'NoTranspose', 'NonUnit',
-     $                        M, IB, ONE, DR, LDDR, DWORK(KFI), M )
-               K = KFI
-               DO 30 J = L, L + IB - 1
-                  DO 20 I = 1, M
-                     CR(I,J) = CR(I,J) + DWORK(K)
-                     K = K + 1
-   20             CONTINUE
-   30          CONTINUE
-C
-               IF( DISCR ) THEN
-C
-C                 Update the input matrix B <-- B*V.
-C
-                  CALL DTRMM( 'Right', 'Upper', 'NoTranspose',
-     $                        'NonUnit', N, M, ONE, DWORK(KV), M, B,
-     $                        LDB )
-C
-C                 Update the feedthrough matrix DR <-- DR*V.
-C
-                  K = KV
-                  DO 40 I = 1, M
-                     CALL DTRMV( 'Upper', 'Transpose', 'NonUnit',
-     $                           M-I+1, DWORK(K), M, DR(I,I), LDDR )
-                     K = K + M + 1
-   40             CONTINUE
-               END IF
-C
-               IF( IB.EQ.2 ) THEN
-C
-C                 Put the 2x2 block in a standard form.
-C
-                  L1 = L + 1
-                  CALL DLANV2( A(L,L), A(L,L1), A(L1,L), A(L1,L1),
-     $                         X, Y, PR, SM, CS, SN )
-C
-C                 Apply the transformation to A, B, C and F.
-C
-                  IF( L1.LT.NSUP )
-     $               CALL DROT( NSUP-L1, A(L,L1+1), LDA, A(L1,L1+1),
-     $                          LDA, CS, SN )
-                  CALL DROT( L-1, A(1,L), 1, A(1,L1), 1, CS, SN )
-                  CALL DROT( M, B(L,1), LDB, B(L1,1), LDB, CS, SN )
-                  IF( P.GT.0 )
-     $               CALL DROT( P, C(1,L), 1, C(1,L1), 1, CS, SN )
-                  CALL DROT( M, CR(1,L), 1, CR(1,L1), 1, CS, SN )
-               END IF
-               IF( NLOW+IB.LE.NSUP ) THEN
-C
-C                 Move the last block(s) to the leading position(s) of
-C                 the bottom block.
-C
-C                 Workspace:     need MAX(4*N, 4*M, 4*P).
-C
-                  NCUR = NSUP - IB
-C                 WHILE (NCUR >= NLOW) DO
-   50             IF( NCUR.GE.NLOW ) THEN
-C
-C                    Loop for positioning of the last block.
-C
-C                    Determine the dimension of the current block.
-C
-                     IB1 = 1
-                     IF( NCUR.GT.NLOW ) THEN
-                         IF( A(NCUR,NCUR-1).NE.ZERO ) IB1 = 2
-                     END IF
-                     NB = IB1 + IB
-C
-C                    Initialize the local transformation matrix Z.
-C
-                     CALL DLASET( 'Full', NB, NB, ZERO, ONE, Z, 4 )
-                     L = NCUR - IB1 + 1
-C
-C                    Exchange two adjacent blocks and accumulate the
-C                    transformations in Z.
-C
-                     CALL DLAEXC( .TRUE., NB, A(L,L), LDA, Z, 4, 1, IB1,
-     $                            IB, DWORK, INFO )
-                     IF( INFO.NE.0 ) THEN
-                        INFO = 2
-                        RETURN
-                     END IF
-C
-C                    Apply the transformation to the rest of A.
-C
-                     L1 = L + NB
-                     IF( L1.LE.NSUP ) THEN
-                        CALL DGEMM( 'Transpose', 'NoTranspose', NB,
-     $                              NSUP-L1+1, NB, ONE, Z, 4, A(L,L1),
-     $                              LDA, ZERO, DWORK, NB )
-                        CALL DLACPY( 'Full', NB, NSUP-L1+1, DWORK, NB,
-     $                               A(L,L1), LDA )
-                     END IF
-                     CALL DGEMM( 'NoTranspose', 'NoTranspose', L-1, NB,
-     $                           NB, ONE, A(1,L), LDA, Z, 4, ZERO,
-     $                           DWORK, N )
-                     CALL DLACPY( 'Full', L-1, NB, DWORK, N, A(1,L),
-     $                            LDA )
-C
-C                    Apply the transformation to B, C and F.
-C
-                     CALL DGEMM( 'Transpose', 'NoTranspose', NB, M, NB,
-     $                           ONE, Z, 4, B(L,1), LDB, ZERO, DWORK,
-     $                           NB )
-                     CALL DLACPY( 'Full', NB, M, DWORK, NB, B(L,1),
-     $                            LDB )
-C
-                     IF( P.GT.0 ) THEN
-                        CALL DGEMM( 'NoTranspose', 'NoTranspose', P, NB,
-     $                              NB, ONE, C(1,L), LDC, Z, 4, ZERO,
-     $                              DWORK, P )
-                        CALL DLACPY( 'Full', P, NB, DWORK, P,
-     $                               C(1,L), LDC )
-                     END IF
-C
-                     CALL DGEMM( 'NoTranspose', 'NoTranspose', M, NB,
-     $                           NB, ONE, CR(1,L), LDCR, Z, 4, ZERO,
-     $                           DWORK, M )
-                     CALL DLACPY( 'Full', M, NB, DWORK, M, CR(1,L),
-     $                            LDCR )
-C
-                     NCUR = NCUR - IB1
-                     GO TO 50
-                  END IF
-C                 END WHILE 50
-C
-               END IF
-               NLOW = NLOW + IB
-            END IF
-            GO TO 10
-         END IF
-C        END WHILE 10
-C
-         NQ = NSUP
-         NR = NSUP - NFP
-C
-C        Annihilate the elements below the first subdiagonal of A.
-C
-         IF( NQ.GT.2 )
-     $      CALL DLASET( 'Lower', NQ-2, NQ-2, ZERO, ZERO, A(3,1), LDA )
-      END IF
-C
-C     Compute C <-- CQ = C + D*F and D <-- DQ = D*DR.
-C
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', P, NQ, M, ONE, D, LDD,
-     $            CR, LDCR, ONE, C, LDC )
-      IF( DISCR )
-     $   CALL DTRMM( 'Right', 'Upper', 'NoTranspose', 'NonUnit', P, M,
-     $               ONE, DR, LDDR, D, LDD )
-C
-      DWORK(1) = MAX( WRKOPT, DBLE( MAX( M*(M+2), 4*M, 4*P ) ) )
-C
-      RETURN
-C *** Last line of SB08DD ***
-      END
--- a/extra/control-devel/src/SB08GD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,256 +0,0 @@
-      SUBROUTINE SB08GD( N, M, P, A, LDA, B, LDB, C, LDC, D, LDD, BR,
-     $                   LDBR, DR, LDDR, IWORK, DWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To construct the state-space representation for the system
-C     G = (A,B,C,D) from the factors Q = (AQR,BQ,CQR,DQ) and
-C     R = (AQR,BR,CQR,DR) of its left coprime factorization
-C                   -1
-C              G = R  * Q,
-C
-C     where G, Q and R are the corresponding transfer-function matrices.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix A. Also the number of rows of the
-C             matrices B and BR and the number of columns of the matrix
-C             C. N represents the order of the systems Q and R.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The dimension of input vector, i.e. the number of columns
-C             of the matrices B and D.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The dimension of output vector, i.e. the number of rows of
-C             the matrices C, D and DR and the number of columns of the
-C             matrices BR and DR.  P >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix AQR of the systems
-C             Q and R.
-C             On exit, the leading N-by-N part of this array contains
-C             the state dynamics matrix of the system G.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input/state matrix BQ of the system Q.
-C             On exit, the leading N-by-M part of this array contains
-C             the input/state matrix of the system G.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the state/output matrix CQR of the systems
-C             Q and R.
-C             On exit, the leading P-by-N part of this array contains
-C             the state/output matrix of the system G.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the input/output matrix DQ of the system Q.
-C             On exit, the leading P-by-M part of this array contains
-C             the input/output matrix of the system G.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     BR      (input) DOUBLE PRECISION array, dimension (LDBR,P)
-C             The leading N-by-P part of this array must contain the
-C             input/state matrix BR of the system R.
-C
-C     LDBR    INTEGER
-C             The leading dimension of array BR.  LDBR >= MAX(1,N).
-C
-C     DR      (input/output) DOUBLE PRECISION array, dimension (LDDR,P)
-C             On entry, the leading P-by-P part of this array must
-C             contain the input/output matrix DR of the system R.
-C             On exit, the leading P-by-P part of this array contains
-C             the LU factorization of the matrix DR, as computed by
-C             LAPACK Library routine DGETRF.
-C
-C     LDDR    INTEGER
-C             The leading dimension of array DR.  LDDR >= MAX(1,P).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (P)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (MAX(1,4*P))
-C             On exit, DWORK(1) contains an estimate of the reciprocal
-C             condition number of the matrix DR.
-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 matrix DR is singular;
-C             = 2:  the matrix DR is numerically singular (warning);
-C                   the calculations continued.
-C
-C     METHOD
-C
-C     The subroutine computes the matrices of the state-space
-C     representation G = (A,B,C,D) by using the formulas:
-C
-C                      -1              -1
-C     A = AQR - BR * DR  * CQR,  C = DR  * CQR,
-C                      -1              -1
-C     B = BQ  - BR * DR  * DQ,   D = DR  * DQ.
-C
-C     REFERENCES
-C
-C     [1] Varga A.
-C         Coprime factors model reduction method based on
-C         square-root balancing-free techniques.
-C         System Analysis, Modelling and Simulation,
-C         vol. 11, pp. 303-311, 1993.
-C
-C     CONTRIBUTOR
-C
-C     C. Oara and A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, July 1998.
-C     Based on the RASP routine LCFI.
-C
-C     REVISIONS
-C
-C     Nov. 1998, V. Sima, Research Institute for Informatics, Bucharest.
-C     Dec. 1998, V. Sima, Katholieke Univ. Leuven, Leuven.
-C
-C     KEYWORDS
-C
-C     Coprime factorization, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER           INFO, LDA, LDB, LDBR, LDC, LDD, LDDR, M, N, P
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), BR(LDBR,*), C(LDC,*),
-     $                  D(LDD,*), DR(LDDR,*), DWORK(*)
-      INTEGER           IWORK(*)
-C     .. Local Scalars
-      DOUBLE PRECISION  DRNORM, RCOND
-C     .. External Functions ..
-      DOUBLE PRECISION  DLAMCH, DLANGE
-      EXTERNAL          DLAMCH, DLANGE
-C     .. External Subroutines ..
-      EXTERNAL          DGECON, DGEMM, DGETRF, DGETRS, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX
-C     .. Executable Statements ..
-C
-      INFO = 0
-C
-C     Check the scalar input parameters.
-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( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -5
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -9
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -11
-      ELSE IF( LDBR.LT.MAX( 1, N ) ) THEN
-         INFO = -13
-      ELSE IF( LDDR.LT.MAX( 1, P ) ) THEN
-         INFO = -15
-      END IF
-      IF( INFO.NE.0 )THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB08GD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( P.EQ.0 )THEN
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Factor the matrix  DR.  First, compute the 1-norm.
-C
-      DRNORM = DLANGE( '1-norm', P, P, DR, LDDR, DWORK )
-      CALL DGETRF( P, P, DR, LDDR, IWORK, INFO )
-      IF( INFO.NE.0 ) THEN
-         INFO = 1
-         DWORK(1) = ZERO
-         RETURN
-      END IF
-C                   -1
-C     Compute C = DR  * CQR.
-C
-      CALL DGETRS( 'NoTranspose', P, N, DR, LDDR, IWORK, C, LDC, INFO )
-C                              -1
-C     Compute A = AQR - BR * DR  * CQR.
-C
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', N, N, P, -ONE, BR, LDBR,
-     $            C, LDC, ONE, A, LDA )
-C                   -1
-C     Compute D = DR  * DQ.
-C
-      CALL DGETRS( 'NoTranspose', P, M, DR, LDDR, IWORK, D, LDD, INFO )
-C                             -1
-C     Compute B = BQ - BR * DR  * DQ.
-C
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', N, M, P, -ONE, BR, LDBR,
-     $            D, LDD, ONE, B, LDB )
-C
-C     Estimate the reciprocal condition number of DR.
-C     Workspace  4*P.
-C
-      CALL DGECON( '1-norm', P, DR, LDDR, DRNORM, RCOND, DWORK, IWORK,
-     $             INFO )
-      IF( RCOND.LE.DLAMCH( 'Epsilon' ) )
-     $   INFO = 2
-C
-      DWORK(1) = RCOND
-C
-      RETURN
-C *** Last line of SB08GD ***
-      END
--- a/extra/control-devel/src/SB08HD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,267 +0,0 @@
-      SUBROUTINE SB08HD( N, M, P, A, LDA, B, LDB, C, LDC, D, LDD, CR,
-     $                   LDCR, DR, LDDR, IWORK, DWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To construct the state-space representation for the system
-C     G = (A,B,C,D) from the factors Q = (AQR,BQR,CQ,DQ) and
-C     R = (AQR,BQR,CR,DR) of its right coprime factorization
-C                       -1
-C              G = Q * R  ,
-C
-C     where G, Q and R are the corresponding transfer-function matrices.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix A. Also the number of rows of the
-C             matrix B and the number of columns of the matrices C and
-C             CR. N represents the order of the systems Q and R.
-C             N >= 0.
-C
-C     M       (input) INTEGER
-C             The dimension of input vector. Also the number of columns
-C             of the matrices B, D and DR and the number of rows of the
-C             matrices CR and DR.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The dimension of output vector. Also the number of rows
-C             of the matrices C and D.  P >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix AQR of the systems
-C             Q and R.
-C             On exit, the leading N-by-N part of this array contains
-C             the state dynamics matrix of the system G.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input/state matrix BQR of the systems Q and R.
-C             On exit, the leading N-by-M part of this array contains
-C             the input/state matrix of the system G.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the state/output matrix CQ of the system Q.
-C             On exit, the leading P-by-N part of this array contains
-C             the state/output matrix of the system G.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, the leading P-by-M part of this array must
-C             contain the input/output matrix DQ of the system Q.
-C             On exit, the leading P-by-M part of this array contains
-C             the input/output matrix of the system G.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     CR      (input) DOUBLE PRECISION array, dimension (LDCR,N)
-C             The leading M-by-N part of this array must contain the
-C             state/output matrix CR of the system R.
-C
-C     LDCR    INTEGER
-C             The leading dimension of array CR.  LDCR >= MAX(1,M).
-C
-C     DR      (input/output) DOUBLE PRECISION array, dimension (LDDR,M)
-C             On entry, the leading M-by-M part of this array must
-C             contain the input/output matrix DR of the system R.
-C             On exit, the leading M-by-M part of this array contains
-C             the LU factorization of the matrix DR, as computed by
-C             LAPACK Library routine DGETRF.
-C
-C     LDDR    INTEGER
-C             The leading dimension of array DR.  LDDR >= MAX(1,M).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (M)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (MAX(1,4*M))
-C             On exit, DWORK(1) contains an estimate of the reciprocal
-C             condition number of the matrix DR.
-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 matrix DR is singular;
-C             = 2:  the matrix DR is numerically singular (warning);
-C                   the calculations continued.
-C
-C     METHOD
-C
-C     The subroutine computes the matrices of the state-space
-C     representation G = (A,B,C,D) by using the formulas:
-C
-C                       -1                   -1
-C     A = AQR - BQR * DR  * CR,  B = BQR * DR  ,
-C                      -1                   -1
-C     C = CQ  - DQ * DR  * CR,   D = DQ * DR  .
-C
-C     REFERENCES
-C
-C     [1] Varga A.
-C         Coprime factors model reduction method based on
-C         square-root balancing-free techniques.
-C         System Analysis, Modelling and Simulation,
-C         vol. 11, pp. 303-311, 1993.
-C
-C     CONTRIBUTOR
-C
-C     C. Oara and A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, July 1998.
-C     Based on the RASP routine RCFI.
-C     V. Sima, Research Institute for Informatics, Bucharest, Nov. 1998,
-C     full BLAS 3 version.
-C
-C     REVISIONS
-C
-C     Dec. 1998, V. Sima, Katholieke Univ. Leuven, Leuven.
-C     Mar. 2000, V. Sima, Research Institute for Informatics, Bucharest.
-C
-C     KEYWORDS
-C
-C     Coprime factorization, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER           INFO, LDA, LDB, LDC, LDCR, LDD, LDDR, M, N, P
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), CR(LDCR,*),
-     $                  D(LDD,*), DR(LDDR,*), DWORK(*)
-      INTEGER           IWORK(*)
-C     .. Local Scalars
-      DOUBLE PRECISION  DRNORM, RCOND
-C     .. External Functions ..
-      DOUBLE PRECISION  DLAMCH, DLANGE
-      EXTERNAL          DLAMCH, DLANGE
-C     .. External Subroutines ..
-      EXTERNAL          DGECON, DGEMM, DGETRF, DTRSM, MA02GD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX
-C     .. Executable Statements ..
-C
-      INFO = 0
-C
-C     Check the scalar input parameters.
-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( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -5
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -9
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -11
-      ELSE IF( LDCR.LT.MAX( 1, M ) ) THEN
-         INFO = -13
-      ELSE IF( LDDR.LT.MAX( 1, M ) ) THEN
-         INFO = -15
-      END IF
-      IF( INFO.NE.0 )THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB08HD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( M.EQ.0 )THEN
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Factor the matrix  DR.  First, compute the 1-norm.
-C
-      DRNORM = DLANGE( '1-norm', M, M, DR, LDDR, DWORK )
-      CALL DGETRF( M, M, DR, LDDR, IWORK, INFO )
-      IF( INFO.NE.0 ) THEN
-         INFO = 1
-         DWORK(1) = ZERO
-         RETURN
-      END IF
-C                         -1
-C     Compute B = BQR * DR  , using the factorization P*DR = L*U.
-C
-      CALL DTRSM( 'Right', 'Upper', 'NoTranspose', 'NonUnit', N, M, ONE,
-     $            DR, LDDR, B, LDB )
-      CALL DTRSM( 'Right', 'Lower', 'NoTranspose', 'Unit', N, M, ONE,
-     $            DR, LDDR, B, LDB )
-      CALL MA02GD( N, B, LDB, 1, M, IWORK, -1 )
-C                               -1
-C     Compute A = AQR - BQR * DR  * CR.
-C
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', N, N, M, -ONE, B, LDB,
-     $            CR, LDCR, ONE, A, LDA )
-C                        -1
-C     Compute D = DQ * DR  .
-C
-      CALL DTRSM( 'Right', 'Upper', 'NoTranspose', 'NonUnit', P, M, ONE,
-     $            DR, LDDR, D, LDD )
-      CALL DTRSM( 'Right', 'Lower', 'NoTranspose', 'Unit', P, M, ONE,
-     $            DR, LDDR, D, LDD )
-      CALL MA02GD( P, D, LDD, 1, M, IWORK, -1 )
-C                             -1
-C     Compute C = CQ - DQ * DR  * CR.
-C
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', P, N, M, -ONE, D, LDD,
-     $            CR, LDCR, ONE, C, LDC )
-C
-C     Estimate the reciprocal condition number of DR.
-C     Workspace  4*M.
-C
-      CALL DGECON( '1-norm', M, DR, LDDR, DRNORM, RCOND, DWORK, IWORK,
-     $             INFO )
-      IF( RCOND.LE.DLAMCH( 'Epsilon' ) )
-     $   INFO = 2
-C
-      DWORK(1) = RCOND
-C
-      RETURN
-C *** Last line of SB08HD ***
-      END
--- a/extra/control-devel/src/SB10YD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,689 +0,0 @@
-      SUBROUTINE SB10YD( DISCFL, FLAG, LENDAT, RFRDAT, IFRDAT, OMEGA, N,
-     $                   A, LDA, B, C, D, TOL, IWORK, DWORK, LDWORK,
-     $                   ZWORK, LZWORK, 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 fit a supplied frequency response data with a stable, minimum
-C     phase SISO (single-input single-output) system represented by its
-C     matrices A, B, C, D. It handles both discrete- and continuous-time
-C     cases.
-C
-C     ARGUMENTS
-C
-C     Input/Output parameters
-C
-C     DISCFL  (input) INTEGER
-C             Indicates the type of the system, as follows:
-C             = 0: continuous-time system;
-C             = 1: discrete-time system.
-C
-C     FLAG    (input) INTEGER
-C             If FLAG = 0, then the system zeros and poles are not
-C             constrained.
-C             If FLAG = 1, then the system zeros and poles will have
-C             negative real parts in the continuous-time case, or moduli
-C             less than 1 in the discrete-time case. Consequently, FLAG
-C             must be equal to 1 in mu-synthesis routines.
-C
-C     LENDAT  (input) INTEGER
-C             The length of the vectors RFRDAT, IFRDAT and OMEGA.
-C             LENDAT >= 2.
-C
-C     RFRDAT  (input) DOUBLE PRECISION array, dimension (LENDAT)
-C             The real part of the frequency data to be fitted.
-C
-C     IFRDAT  (input) DOUBLE PRECISION array, dimension (LENDAT)
-C             The imaginary part of the frequency data to be fitted.
-C
-C     OMEGA   (input) DOUBLE PRECISION array, dimension (LENDAT)
-C             The frequencies corresponding to RFRDAT and IFRDAT.
-C             These values must be nonnegative and monotonically
-C             increasing. Additionally, for discrete-time systems
-C             they must be between 0 and PI.
-C
-C     N       (input/output) INTEGER
-C             On entry, the desired order of the system to be fitted.
-C             N <= LENDAT-1.
-C             On exit, the order of the obtained system. The value of N
-C             could only be modified if N > 0 and FLAG = 1.
-C
-C     A       (output) DOUBLE PRECISION array, dimension (LDA,N)
-C             The leading N-by-N part of this array contains the
-C             matrix A. If FLAG = 1, then A is in an upper Hessenberg
-C             form, and corresponds to a minimal realization.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= MAX(1,N).
-C
-C     B       (output) DOUBLE PRECISION array, dimension (N)
-C             The computed vector B.
-C
-C     C       (output) DOUBLE PRECISION array, dimension (N)
-C             The computed vector C. If FLAG = 1, the first N-1 elements
-C             are zero (for the exit value of N).
-C
-C     D       (output) DOUBLE PRECISION array, dimension (1)
-C             The computed scalar D.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used for determining the effective
-C             rank of matrices. If the user sets TOL > 0, then the given
-C             value of TOL is used as a lower bound for the reciprocal
-C             condition number;  a (sub)matrix whose estimated condition
-C             number is less than 1/TOL is considered to be of full
-C             rank.  If the user sets TOL <= 0, then an implicitly
-C             computed, default tolerance, defined by TOLDEF = SIZE*EPS,
-C             is used instead, where SIZE is the product of the matrix
-C             dimensions, and EPS is the machine precision (see LAPACK
-C             Library routine DLAMCH).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension max(2,2*N+1)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK and DWORK(2) contains the optimal value of
-C             LZWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK = max( 2, LW1, LW2, LW3, LW4 ), where
-C             LW1 = 2*LENDAT + 4*HNPTS;  HNPTS = 2048;
-C             LW2 =   LENDAT + 6*HNPTS;
-C             MN  = min( 2*LENDAT, 2*N+1 )
-C             LW3 = 2*LENDAT*(2*N+1) + max( 2*LENDAT, 2*N+1 ) +
-C                   max( MN + 6*N + 4, 2*MN + 1 ), if N > 0;
-C             LW3 = 4*LENDAT + 5                 , if N = 0;
-C             LW4 = max( N*N + 5*N, 6*N + 1 + min( 1,N ) ), if FLAG = 1;
-C             LW4 = 0,                                      if FLAG = 0.
-C             For optimum performance LDWORK should be larger.
-C
-C     ZWORK   COMPLEX*16 array, dimension (LZWORK)
-C
-C     LZWORK  INTEGER
-C             The length of the array ZWORK.
-C             LZWORK = LENDAT*(2*N+3), if N > 0;
-C             LZWORK = LENDAT,         if N = 0.
-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 discrete --> continuous transformation cannot
-C                   be made;
-C             = 2:  if the system poles cannot be found;
-C             = 3:  if the inverse system cannot be found, i.e., D is
-C                   (close to) zero;
-C             = 4:  if the system zeros cannot be found;
-C             = 5:  if the state-space representation of the new
-C                   transfer function T(s) cannot be found;
-C             = 6:  if the continuous --> discrete transformation cannot
-C                   be made.
-C
-C     METHOD
-C
-C     First, if the given frequency data are corresponding to a
-C     continuous-time system, they are changed to a discrete-time
-C     system using a bilinear transformation with a scaled alpha.
-C     Then, the magnitude is obtained from the supplied data.
-C     Then, the frequency data are linearly interpolated around
-C     the unit-disc.
-C     Then, Oppenheim and Schafer complex cepstrum method is applied
-C     to get frequency data corresponding to a stable, minimum-
-C     phase system. This is done in the following steps:
-C     - Obtain LOG (magnitude)
-C     - Obtain IFFT of the result (DG01MD SLICOT subroutine);
-C     - halve the data at 0;
-C     - Obtain FFT of the halved data (DG01MD SLICOT subroutine);
-C     - Obtain EXP of the result.
-C     Then, the new frequency data are interpolated back to the
-C     original frequency.
-C     Then, based on these newly obtained data, the system matrices
-C     A, B, C, D are constructed; the very identification is
-C     performed by Least Squares Method using DGELSY LAPACK subroutine.
-C     If needed, a discrete-to-continuous time transformation is
-C     applied on the system matrices by AB04MD SLICOT subroutine.
-C     Finally, if requested, the poles and zeros of the system are
-C     checked. If some of them have positive real parts in the
-C     continuous-time case (or are not inside the unit disk in the
-C     complex plane in the discrete-time case), they are exchanged with
-C     their negatives (or reciprocals, respectively), to preserve the
-C     frequency response, while getting a minimum phase and stable
-C     system. This is done by SB10ZP SLICOT subroutine.
-C
-C     REFERENCES
-C
-C     [1] Oppenheim, A.V. and Schafer, R.W.
-C         Discrete-Time Signal Processing.
-C         Prentice-Hall Signal Processing Series, 1989.
-C
-C     [2] Balas, G., Doyle, J., Glover, K., Packard, A., and Smith, R.
-C         Mu-analysis and Synthesis toolbox - User's Guide,
-C         The Mathworks Inc., Natick, MA, USA, 1998.
-C
-C     CONTRIBUTORS
-C
-C     Asparuh Markovski, Technical University of Sofia, July 2003.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 2003.
-C     A. Markovski, Technical University of Sofia, October 2003.
-C
-C     KEYWORDS
-C
-C     Bilinear transformation, frequency response, least-squares
-C     approximation, stability.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      COMPLEX*16         ZZERO, ZONE
-      PARAMETER          ( ZZERO = ( 0.0D+0, 0.0D+0 ),
-     $                     ZONE  = ( 1.0D+0, 0.0D+0 ) )
-      DOUBLE PRECISION   ZERO, ONE, TWO, FOUR, TEN
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0, TWO = 2.0D+0,
-     $                     FOUR = 4.0D+0, TEN = 1.0D+1 )
-      INTEGER            HNPTS
-      PARAMETER          ( HNPTS = 2048 )
-C     ..
-C     .. Scalar Arguments ..
-      INTEGER            DISCFL, FLAG, INFO, LDA, LDWORK, LENDAT,
-     $                   LZWORK, N
-      DOUBLE PRECISION   TOL
-C     ..
-C     .. Array Arguments ..
-      INTEGER            IWORK(*)
-      DOUBLE PRECISION   A(LDA, *), B(*), C(*), D(*), DWORK(*),
-     $                   IFRDAT(*), OMEGA(*), RFRDAT(*)
-      COMPLEX*16         ZWORK(*)
-C     ..
-C     .. Local Scalars ..
-      INTEGER            CLWMAX, DLWMAX, I, II, INFO2, IP1, IP2, ISTART,
-     $                   ISTOP, IWA0, IWAB, IWBMAT, IWBP, IWBX, IWDME,
-     $                   IWDOMO, IWMAG, IWS, IWVAR, IWXI, IWXR, IWYMAG,
-     $                   K, LW1, LW2, LW3, LW4, MN, N1, N2, P, RANK
-      DOUBLE PRECISION   P1, P2, PI, PW, RAT, TOLB, TOLL
-      COMPLEX*16         XHAT(HNPTS/2)
-C     ..
-C     .. External Functions ..
-      DOUBLE PRECISION   DLAMCH, DLAPY2
-      EXTERNAL           DLAMCH, DLAPY2
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           AB04MD, DCOPY, DG01MD, DGELSY, DLASET, DSCAL,
-     $                   SB10ZP, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ACOS, ATAN, COS, DBLE, DCMPLX, DIMAG, EXP, LOG,
-     $                   MAX, MIN, SIN, SQRT
-C
-C     Test input parameters and workspace.
-C
-      PI = FOUR*ATAN( ONE )
-      PW = OMEGA(1)
-      N1 = N + 1
-      N2 = N + N1
-C
-      INFO = 0
-      IF( DISCFL.NE.0 .AND. DISCFL.NE.1 ) THEN
-         INFO = -1
-      ELSE IF( FLAG.NE.0 .AND. FLAG.NE.1 ) THEN
-         INFO = -2
-      ELSE IF ( LENDAT.LT.2 ) THEN
-         INFO = -3
-      ELSE IF ( PW.LT.ZERO ) THEN
-         INFO = -6
-      ELSE IF( N.GT.LENDAT - 1 ) THEN
-         INFO = -7
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE
-C
-         DO 10 K = 2, LENDAT
-            IF ( OMEGA(K).LT.PW )
-     $         INFO = -6
-            PW = OMEGA(K)
-   10    CONTINUE
-C
-         IF ( DISCFL.EQ.1 .AND. OMEGA(LENDAT).GT.PI )
-     $      INFO = -6
-      END IF
-C
-      IF ( INFO.EQ.0 ) THEN
-C
-C        Workspace.
-C
-         LW1 = 2*LENDAT + 4*HNPTS
-         LW2 =   LENDAT + 6*HNPTS
-         MN  = MIN( 2*LENDAT, N2 )
-C
-         IF ( N.GT.0 ) THEN
-            LW3 = 2*LENDAT*N2 + MAX( 2*LENDAT, N2 ) +
-     $                          MAX( MN + 6*N + 4, 2*MN + 1 )
-         ELSE
-            LW3 = 4*LENDAT + 5
-         END IF
-C
-         IF ( FLAG.EQ.0 ) THEN
-            LW4 = 0
-         ELSE
-            LW4 = MAX( N*N + 5*N, 6*N + 1 + MIN ( 1, N ) )
-         END IF
-C
-         DLWMAX = MAX( 2, LW1, LW2, LW3, LW4 )
-C
-         IF ( N.GT.0 ) THEN
-            CLWMAX = LENDAT*( N2 + 2 )
-         ELSE
-            CLWMAX = LENDAT
-         END IF
-C
-         IF ( LDWORK.LT.DLWMAX ) THEN
-            INFO = -16
-         ELSE IF ( LZWORK.LT.CLWMAX ) THEN
-            INFO = -18
-         END IF
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB10YD', -INFO )
-         RETURN
-      END IF
-C
-C     Set tolerances.
-C
-      TOLB = DLAMCH( 'Epsilon' )
-      TOLL = TOL
-      IF ( TOLL.LE.ZERO )
-     $   TOLL = FOUR*DBLE( LENDAT*N )*TOLB
-C
-C     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-C
-C     Workspace usage 1.
-C     Workspace:  need  2*LENDAT + 4*HNPTS.
-C
-      IWDOMO = 1
-      IWDME  = IWDOMO + LENDAT
-      IWYMAG = IWDME  + 2*HNPTS
-      IWMAG  = IWYMAG + 2*HNPTS
-C
-C     Bilinear transformation.
-C
-      IF ( DISCFL.EQ.0 ) THEN
-         PW = SQRT( OMEGA(1)*OMEGA(LENDAT) + SQRT( TOLB ) )
-C
-         DO 20 K = 1, LENDAT
-            DWORK(IWDME+K-1)  = ( OMEGA(K)/PW )**2
-            DWORK(IWDOMO+K-1) =
-     $         ACOS( ( ONE - DWORK(IWDME+K-1) )/
-     $               ( ONE + DWORK(IWDME+K-1) ) )
-   20    CONTINUE
-C
-      ELSE
-         CALL DCOPY( LENDAT, OMEGA, 1, DWORK(IWDOMO), 1 )
-      END IF
-C
-C     Linear interpolation.
-C
-      DO 30 K = 1, LENDAT
-         DWORK(IWMAG+K-1) = DLAPY2( RFRDAT(K), IFRDAT(K) )
-         DWORK(IWMAG+K-1) = ( ONE/LOG( TEN ) ) * LOG( DWORK(IWMAG+K-1) )
-   30 CONTINUE
-C
-      DO 40 K = 1, HNPTS
-         DWORK(IWDME+K-1)  = ( K - 1 )*PI/HNPTS
-         DWORK(IWYMAG+K-1) = ZERO
-C
-         IF ( DWORK(IWDME+K-1).LT.DWORK(IWDOMO) ) THEN
-            DWORK(IWYMAG+K-1) = DWORK(IWMAG)
-         ELSE IF ( DWORK(IWDME+K-1).GE.DWORK(IWDOMO+LENDAT-1) ) THEN
-            DWORK(IWYMAG+K-1) = DWORK(IWMAG+LENDAT-1)
-         END IF
-C
-   40 CONTINUE
-C
-      DO 60 I = 2, LENDAT
-         P1 = HNPTS*DWORK(IWDOMO+I-2)/PI + ONE
-C
-         IP1 = INT( P1 )
-         IF ( DBLE( IP1 ).NE.P1 )
-     $      IP1 = IP1 + 1
-C
-         P2 = HNPTS*DWORK(IWDOMO+I-1)/PI + ONE
-C
-         IP2 = INT( P2 )
-         IF ( DBLE( IP2 ).NE.P2 )
-     $      IP2 = IP2 + 1
-C
-         DO 50 P = IP1, IP2 - 1
-            RAT = DWORK(IWDME+P-1) - DWORK(IWDOMO+I-2)
-            RAT = RAT/( DWORK(IWDOMO+I-1) - DWORK(IWDOMO+I-2) )
-            DWORK(IWYMAG+P-1) = ( ONE - RAT )*DWORK(IWMAG+I-2) +
-     $                          RAT*DWORK(IWMAG+I-1)
-   50    CONTINUE
-C
-   60 CONTINUE
-C
-      DO 70 K = 1, HNPTS
-         DWORK(IWYMAG+K-1) = EXP( LOG( TEN )*DWORK(IWYMAG+K-1) )
-   70 CONTINUE
-C
-C     Duplicate data around disc.
-C
-      DO 80 K = 1, HNPTS
-         DWORK(IWDME+HNPTS+K-1)  = TWO*PI - DWORK(IWDME+HNPTS-K)
-         DWORK(IWYMAG+HNPTS+K-1) = DWORK(IWYMAG+HNPTS-K)
-   80 CONTINUE
-C
-C     Complex cepstrum to get min phase:
-C     LOG (Magnitude)
-C
-      DO 90 K = 1, 2*HNPTS
-         DWORK(IWYMAG+K-1) = TWO*LOG( DWORK(IWYMAG+K-1) )
-   90 CONTINUE
-C
-C     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-C
-C     Workspace usage 2.
-C     Workspace:  need  LENDAT + 6*HNPTS.
-C
-      IWXR = IWYMAG
-      IWXI = IWMAG
-C
-      DO 100 K = 1, 2*HNPTS
-         DWORK(IWXI+K-1) = ZERO
-  100 CONTINUE
-C
-C     IFFT
-C
-      CALL DG01MD( 'I', 2*HNPTS, DWORK(IWXR), DWORK(IWXI), INFO2 )
-C
-C     Rescale, because DG01MD doesn't do it.
-C
-      CALL DSCAL( HNPTS, ONE/( TWO*HNPTS ), DWORK(IWXR), 1 )
-      CALL DSCAL( HNPTS, ONE/( TWO*HNPTS ), DWORK(IWXI), 1 )
-C
-C     Halve the result at 0.
-C
-      DWORK(IWXR) = DWORK(IWXR)/TWO
-      DWORK(IWXI) = DWORK(IWXI)/TWO
-C
-C     FFT
-C
-      CALL DG01MD( 'D', HNPTS, DWORK(IWXR), DWORK(IWXI), INFO2 )
-C
-C     Get the EXP of the result.
-C
-      DO 110 K = 1, HNPTS/2
-         XHAT(K) = EXP( DWORK(IWXR+K-1) )*
-     $         DCMPLX ( COS( DWORK(IWXI+K-1)), SIN( DWORK(IWXI+K-1) ) )
-         DWORK(IWDME+K-1) = DWORK(IWDME+2*K-2)
-  110 CONTINUE
-C
-C     Interpolate back to original frequency data.
-C
-      ISTART = 1
-      ISTOP  = LENDAT
-C
-      DO 120 I = 1, LENDAT
-         ZWORK(I) = ZZERO
-         IF ( DWORK(IWDOMO+I-1).LE.DWORK(IWDME) ) THEN
-            ZWORK(I) = XHAT(1)
-            ISTART = I + 1
-         ELSE IF ( DWORK(IWDOMO+I-1).GE.DWORK(IWDME+HNPTS/2-1) )
-     $         THEN
-            ZWORK(I) = XHAT(HNPTS/2)
-            ISTOP = ISTOP - 1
-         END IF
-  120 CONTINUE
-C
-      DO 140 I = ISTART, ISTOP
-         II = HNPTS/2
-  130    CONTINUE
-            IF ( DWORK(IWDME+II-1).GE.DWORK(IWDOMO+I-1) )
-     $         P = II
-            II = II - 1
-         IF ( II.GT.0 )
-     $      GOTO 130
-         RAT = ( DWORK(IWDOMO+I-1) - DWORK(IWDME+P-2) )/
-     $         ( DWORK(IWDME+P-1)  - DWORK(IWDME+P-2) )
-         ZWORK(I) = RAT*XHAT(P) + ( ONE - RAT )*XHAT(P-1)
-  140 CONTINUE
-C
-C     CASE N > 0.
-C     This is the only allowed case in mu-synthesis subroutines.
-C
-      IF ( N.GT.0 ) THEN
-C
-C        Preparation for frequency identification.
-C
-C        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-C
-C        Complex workspace usage 1.
-C        Complex workspace:  need  2*LENDAT + LENDAT*(N+1).
-C
-         IWA0  = 1 + LENDAT
-         IWVAR = IWA0 + LENDAT*N1
-C
-         DO 150 K = 1, LENDAT
-            IF ( DISCFL.EQ.0 ) THEN
-               ZWORK(IWVAR+K-1) = DCMPLX( COS( DWORK(IWDOMO+K-1) ),
-     $                                    SIN( DWORK(IWDOMO+K-1) ) )
-            ELSE
-               ZWORK(IWVAR+K-1) = DCMPLX( COS( OMEGA(K) ),
-     $                                    SIN( OMEGA(K) ) )
-            END IF
-  150    CONTINUE
-C
-C        Array for DGELSY.
-C
-         DO 160 K = 1, N2
-            IWORK(K) = 0
-  160    CONTINUE
-C
-C        Constructing A0.
-C
-         DO 170 K = 1, LENDAT
-            ZWORK(IWA0+N*LENDAT+K-1) = ZONE
-  170    CONTINUE
-C
-         DO 190 I = 1, N
-            DO 180 K = 1, LENDAT
-               ZWORK(IWA0+(N-I)*LENDAT+K-1) =
-     $            ZWORK(IWA0+(N1-I)*LENDAT+K-1)*ZWORK(IWVAR+K-1)
-  180       CONTINUE
-  190    CONTINUE
-C
-C        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-C
-C        Complex workspace usage 2.
-C        Complex workspace:  need  2*LENDAT + LENDAT*(2*N+1).
-C
-         IWBP = IWVAR
-         IWAB = IWBP + LENDAT
-C
-C        Constructing BP.
-C
-         DO 200 K = 1, LENDAT
-            ZWORK(IWBP+K-1) = ZWORK(IWA0+K-1)*ZWORK(K)
-  200    CONTINUE
-C
-C        Constructing AB.
-C
-         DO 220 I = 1, N
-            DO 210 K = 1, LENDAT
-               ZWORK(IWAB+(I-1)*LENDAT+K-1) = -ZWORK(K)*
-     $             ZWORK(IWA0+I*LENDAT+K-1)
-  210       CONTINUE
-  220    CONTINUE
-C
-C        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-C
-C        Workspace usage 3.
-C        Workspace:  need  LW3 = 2*LENDAT*(2*N+1) + max(2*LENDAT,2*N+1).
-C
-         IWBX = 1 + 2*LENDAT*N2
-         IWS  = IWBX + MAX( 2*LENDAT, N2 )
-C
-C        Constructing AX.
-C
-         DO 240 I = 1, N1
-            DO 230 K = 1, LENDAT
-               DWORK(2*(I-1)*LENDAT+K) =
-     $            DBLE( ZWORK(IWA0+(I-1)*LENDAT+K-1) )
-               DWORK((2*I-1)*LENDAT+K) =
-     $            DIMAG( ZWORK(IWA0+(I-1)*LENDAT+K-1) )
-  230       CONTINUE
-  240    CONTINUE
-C
-         DO 260 I = 1, N
-            DO 250 K = 1, LENDAT
-               DWORK(2*N1*LENDAT+2*(I-1)*LENDAT+K) =
-     $            DBLE( ZWORK(IWAB+(I-1)*LENDAT+K-1) )
-               DWORK(2*N1*LENDAT+(2*I-1)*LENDAT+K) =
-     $            DIMAG( ZWORK(IWAB+(I-1)*LENDAT+K-1) )
-  250       CONTINUE
-  260    CONTINUE
-C
-C        Constructing BX.
-C
-         DO 270 K = 1, LENDAT
-            DWORK(IWBX+K-1) = DBLE( ZWORK(IWBP+K-1) )
-            DWORK(IWBX+LENDAT+K-1) = DIMAG( ZWORK(IWBP+K-1) )
-  270    CONTINUE
-C
-C        Estimating X.
-C        Workspace:  need    LW3 + max( MN+3*(2*N+1)+1, 2*MN+1 ),
-C                            where MN = min( 2*LENDAT, 2*N+1 );
-C                            prefer  larger.
-C
-         CALL DGELSY( 2*LENDAT, N2, 1, DWORK, 2*LENDAT, DWORK(IWBX),
-     $                MAX( 2*LENDAT, N2 ), IWORK, TOLL, RANK,
-     $                DWORK(IWS), LDWORK-IWS+1, INFO2 )
-         DLWMAX = MAX( DLWMAX, INT( DWORK(IWS) + IWS - 1 ) )
-C
-C        Constructing A matrix.
-C
-         DO 280 K = 1, N
-            A(K,1) = -DWORK(IWBX+N1+K-1)
-  280    CONTINUE
-C
-         IF ( N.GT.1 )
-     $      CALL DLASET( 'Full', N, N-1, ZERO, ONE, A(1,2), LDA )
-C
-C        Constructing B matrix.
-C
-         DO 290 K = 1, N
-            B(K) = DWORK(IWBX+N1+K-1)*DWORK(IWBX) - DWORK(IWBX+K)
-  290    CONTINUE
-C
-C        Constructing C matrix.
-C
-         C(1) = -ONE
-C
-         DO 300 K = 2, N
-            C(K) = ZERO
-  300    CONTINUE
-C
-C        Constructing D matrix.
-C
-         D(1) = DWORK(IWBX)
-C
-C        Transform to continuous-time case, if needed.
-C        Workspace:  need    max(1,N);
-C                            prefer  larger.
-C
-         IF ( DISCFL.EQ.0 ) THEN
-            CALL AB04MD( 'D', N, 1, 1, ONE, PW, A, LDA, B, LDA, C, 1,
-     $                   D, 1, IWORK, DWORK, LDWORK, INFO2 )
-            IF ( INFO2.NE.0 ) THEN
-               INFO = 1
-               RETURN
-            END IF
-            DLWMAX = MAX( DLWMAX, INT( DWORK(1) ) )
-         END IF
-C
-C        Make all the real parts of the poles and the zeros negative.
-C
-         IF ( FLAG.EQ.1 ) THEN
-C
-C           Workspace:  need    max(N*N + 5*N, 6*N + 1 + min(1,N));
-C                               prefer  larger.
-            CALL SB10ZP( DISCFL, N, A, LDA, B, C, D, IWORK, DWORK,
-     $                   LDWORK, INFO )
-            IF ( INFO.NE.0 )
-     $         RETURN
-            DLWMAX = MAX( DLWMAX, INT( DWORK(1) ) )
-         END IF
-C
-       ELSE
-C
-C        CASE N = 0.
-C
-C        @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-C
-C        Workspace usage 4.
-C        Workspace:  need  4*LENDAT.
-C
-         IWBMAT = 1 + 2*LENDAT
-         IWS    = IWBMAT + 2*LENDAT
-C
-C        Constructing AMAT and BMAT.
-C
-         DO 310 K = 1, LENDAT
-            DWORK(K) = ONE
-            DWORK(K+LENDAT) = ZERO
-            DWORK(IWBMAT+K-1) = DBLE( ZWORK(K) )
-            DWORK(IWBMAT+LENDAT+K-1) = DIMAG( ZWORK(K) )
-  310    CONTINUE
-C
-C        Estimating D matrix.
-C        Workspace:  need    4*LENDAT + 5;
-C                            prefer  larger.
-C
-         IWORK(1) = 0
-         CALL DGELSY( 2*LENDAT, 1, 1, DWORK, 2*LENDAT, DWORK(IWBMAT),
-     $                2*LENDAT, IWORK, TOLL, RANK, DWORK(IWS),
-     $                LDWORK-IWS+1, INFO2 )
-         DLWMAX = MAX( DLWMAX, INT( DWORK(IWS) + IWS - 1 ) )
-C
-         D(1) = DWORK(IWBMAT)
-C
-      END IF
-C
-C     @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-C
-      DWORK(1) = DLWMAX
-      DWORK(2) = CLWMAX
-      RETURN
-C
-C *** Last line of SB10YD ***
-      END
--- a/extra/control-devel/src/SB10ZP.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,339 +0,0 @@
-      SUBROUTINE SB10ZP( DISCFL, N, A, LDA, B, C, D, 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 transform a SISO (single-input single-output) system [A,B;C,D]
-C     by mirroring its unstable poles and zeros in the boundary of the
-C     stability domain, thus preserving the frequency response of the
-C     system, but making it stable and minimum phase. Specifically, for
-C     a continuous-time system, the positive real parts of its poles
-C     and zeros are exchanged with their negatives. Discrete-time
-C     systems are first converted to continuous-time systems using a
-C     bilinear transformation, and finally converted back.
-C
-C     ARGUMENTS
-C
-C     Input/Output parameters
-C
-C     DISCFL  (input) INTEGER
-C             Indicates the type of the system, as follows:
-C             = 0: continuous-time system;
-C             = 1: discrete-time system.
-C
-C     N       (input/output) INTEGER
-C             On entry, the order of the original system.  N >= 0.
-C             On exit, the order of the transformed, minimal system.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the original system matrix A.
-C             On exit, the leading N-by-N part of this array contains
-C             the transformed matrix A, in an upper Hessenberg form.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (N)
-C             On entry, this array must contain the original system
-C             vector B.
-C             On exit, this array contains the transformed vector B.
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (N)
-C             On entry, this array must contain the original system
-C             vector C.
-C             On exit, this array contains the transformed vector C.
-C             The first N-1 elements are zero (for the exit value of N).
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension (1)
-C             On entry, this array must contain the original system
-C             scalar D.
-C             On exit, this array contains the transformed scalar D.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension max(2,N+1)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= max(N*N + 5*N, 6*N + 1 + min(1,N)).
-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 discrete --> continuous transformation cannot
-C                   be made;
-C             = 2:  if the system poles cannot be found;
-C             = 3:  if the inverse system cannot be found, i.e., D is
-C                   (close to) zero;
-C             = 4:  if the system zeros cannot be found;
-C             = 5:  if the state-space representation of the new
-C                   transfer function T(s) cannot be found;
-C             = 6:  if the continuous --> discrete transformation cannot
-C                   be made.
-C
-C     METHOD
-C
-C     First, if the system is discrete-time, it is transformed to
-C     continuous-time using alpha = beta = 1 in the bilinear
-C     transformation implemented in the SLICOT routine AB04MD.
-C     Then the eigenvalues of A, i.e., the system poles, are found.
-C     Then, the inverse of the original system is found and its poles,
-C     i.e., the system zeros, are evaluated.
-C     The obtained system poles Pi and zeros Zi are checked and if a
-C     positive real part is detected, it is exchanged by -Pi or -Zi.
-C     Then the polynomial coefficients of the transfer function
-C     T(s) = Q(s)/P(s) are found.
-C     The state-space representation of T(s) is then obtained.
-C     The system matrices B, C, D are scaled so that the transformed
-C     system has the same system gain as the original system.
-C     If the original system is discrete-time, then the result (which is
-C     continuous-time) is converted back to discrete-time.
-C
-C     CONTRIBUTORS
-C
-C     Asparuh Markovski, Technical University of Sofia, July 2003.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 2003.
-C
-C     KEYWORDS
-C
-C     Bilinear transformation, stability, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      INTEGER            DISCFL, INFO, LDA, LDWORK, N
-C     ..
-C     .. Array Arguments ..
-      INTEGER            IWORK( * )
-      DOUBLE PRECISION   A( LDA, * ), B( * ), C( * ), D( * ), DWORK( * )
-C     ..
-C     .. Local Scalars ..
-      INTEGER            I, IDW1, IDW2, IDW3, IMP, IMZ, INFO2, IWA, IWP,
-     $                   IWPS, IWQ, IWQS, LDW1, MAXWRK, REP, REZ
-      DOUBLE PRECISION   RCOND, SCALB, SCALC, SCALD
-C     ..
-C     .. Local Arrays ..
-      INTEGER            INDEX(1)
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           AB04MD, AB07ND, DCOPY, DGEEV, DLACPY, DSCAL,
-     $                   MC01PD, TD04AD, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, INT, MAX, MIN, SIGN, SQRT
-C
-C     Test input parameters and workspace.
-C
-      INFO = 0
-      IF ( DISCFL.NE.0 .AND. DISCFL.NE.1 ) THEN
-         INFO = -1
-      ELSE IF ( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -4
-      ELSE IF ( LDWORK.LT.MAX( N*N + 5*N, 6*N + 1 + MIN( 1, N ) ) ) THEN
-         INFO = -10
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB10ZP', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( N.EQ.0 ) THEN
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Workspace usage 1.
-C
-      REP  = 1
-      IMP  = REP + N
-      REZ  = IMP + N
-      IMZ  = REZ + N
-      IWA  = REZ
-      IDW1 = IWA + N*N
-      LDW1 = LDWORK - IDW1 + 1
-C
-C     1. Discrete --> continuous transformation if needed.
-C
-      IF ( DISCFL.EQ.1 ) THEN
-C
-C        Workspace:  need    max(1,N);
-C                            prefer  larger.
-C
-         CALL AB04MD( 'D', N, 1, 1, ONE, ONE, A, LDA, B, LDA, C, 1,
-     $                D, 1, IWORK, DWORK, LDWORK, INFO2 )
-         IF ( INFO2.NE.0 ) THEN
-            INFO = 1
-            RETURN
-         END IF
-         MAXWRK = INT( DWORK(1) )
-      ELSE
-         MAXWRK = 0
-      END IF
-C
-C     2. Determine the factors for restoring system gain.
-C
-      SCALD = D(1)
-      SCALC = SQRT( ABS( SCALD ) )
-      SCALB = SIGN( SCALC, SCALD )
-C
-C     3. Find the system poles, i.e., the eigenvalues of A.
-C        Workspace:  need    N*N + 2*N + 3*N;
-C                            prefer  larger.
-C
-      CALL DLACPY( 'Full', N, N, A, LDA, DWORK(IWA), N )
-C
-      CALL DGEEV( 'N', 'N', N, DWORK(IWA), N, DWORK(REP), DWORK(IMP),
-     $            DWORK(IDW1), 1, DWORK(IDW1), 1, DWORK(IDW1), LDW1,
-     $            INFO2 )
-      IF ( INFO2.NE.0 ) THEN
-         INFO = 2
-         RETURN
-      END IF
-      MAXWRK = MAX( MAXWRK, INT( DWORK(IDW1) + IDW1 - 1 ) )
-C
-C     4. Compute the inverse system [Ai, Bi; Ci, Di].
-C        Workspace:  need    N*N + 2*N + 4;
-C                            prefer  larger.
-C
-      CALL AB07ND( N, 1, A, LDA, B, LDA, C, 1, D, 1, RCOND, IWORK,
-     $             DWORK(IDW1), LDW1, INFO2 )
-      IF ( INFO2.NE.0 ) THEN
-         INFO = 3
-         RETURN
-      END IF
-      MAXWRK = MAX( MAXWRK, INT( DWORK(IDW1) + IDW1 - 1 ) )
-C
-C     5. Find the system zeros, i.e., the eigenvalues of Ai.
-C        Workspace:  need    4*N + 3*N;
-C                            prefer  larger.
-C
-      IDW1 = IMZ + N
-      LDW1 = LDWORK - IDW1 + 1
-C
-      CALL DGEEV( 'N', 'N', N, A, LDA, DWORK(REZ), DWORK(IMZ),
-     $            DWORK(IDW1), 1, DWORK(IDW1), 1, DWORK(IDW1), LDW1,
-     $            INFO2 )
-      IF ( INFO2.NE.0 ) THEN
-         INFO = 4
-         RETURN
-      END IF
-      MAXWRK = MAX( MAXWRK, INT( DWORK(IDW1) + IDW1 - 1 ) )
-C
-C     6. Exchange the zeros and the poles with positive real parts with
-C        their negatives.
-C
-      DO 10 I = 0, N - 1
-         IF ( DWORK(REP+I).GT.ZERO )
-     $      DWORK(REP+I) = -DWORK(REP+I)
-         IF ( DWORK(REZ+I).GT.ZERO )
-     $      DWORK(REZ+I) = -DWORK(REZ+I)
-   10 CONTINUE
-C
-C     Workspace usage 2.
-C
-      IWP  = IDW1
-      IDW2 = IWP + N + 1
-      IWPS = 1
-C
-C     7. Construct the nominator and the denominator
-C        of the system transfer function T( s ) = Q( s )/P( s ).
-C     8. Rearrange the coefficients in Q(s) and P(s) because
-C        MC01PD subroutine produces them in increasing powers of s.
-C        Workspace:  need    6*N + 2.
-C
-      CALL MC01PD( N, DWORK(REP), DWORK(IMP), DWORK(IWP), DWORK(IDW2),
-     $             INFO2 )
-      CALL DCOPY( N+1, DWORK(IWP), -1, DWORK(IWPS), 1 )
-C
-C     Workspace usage 3.
-C
-      IWQ  = IDW1
-      IWQS = IWPS + N + 1
-      IDW3 = IWQS + N + 1
-C
-      CALL MC01PD( N, DWORK(REZ), DWORK(IMZ), DWORK(IWQ), DWORK(IDW2),
-     $             INFO2 )
-      CALL DCOPY( N+1, DWORK(IWQ), -1, DWORK(IWQS), 1 )
-C
-C     9. Make the conversion T(s) --> [A, B; C, D].
-C        Workspace:  need    2*N + 2 + N + max(N,3);
-C                            prefer  larger.
-C
-      INDEX(1) = N
-      CALL TD04AD( 'R', 1, 1, INDEX, DWORK(IWPS), 1, DWORK(IWQS), 1, 1,
-     $             N, A, LDA, B, LDA, C, 1, D, 1, -ONE, IWORK,
-     $             DWORK(IDW3), LDWORK-IDW3+1, INFO2 )
-      IF ( INFO2.NE.0 ) THEN
-         INFO = 5
-         RETURN
-      END IF
-      MAXWRK = MAX( MAXWRK, INT( DWORK(IDW3) + IDW3 - 1 ) )
-C
-C    10. Scale the transformed system to the previous gain.
-C
-      IF ( N.GT.0 ) THEN
-         CALL DSCAL( N, SCALB, B, 1 )
-         C(N) = SCALC*C(N)
-      END IF
-C
-      D(1) = SCALD
-C
-C     11. Continuous --> discrete transformation if needed.
-C
-      IF ( DISCFL.EQ.1 ) THEN
-         CALL AB04MD( 'C', N, 1, 1, ONE, ONE, A, LDA, B, LDA, C, 1,
-     $                D, 1, IWORK, DWORK, LDWORK, INFO2 )
-
-         IF ( INFO2.NE.0 ) THEN
-            INFO = 6
-            RETURN
-         END IF
-      END IF
-C
-      DWORK(1) = MAXWRK
-      RETURN
-C
-C *** Last line of SB10ZP ***
-      END
--- a/extra/control-devel/src/SB16AD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,719 +0,0 @@
-      SUBROUTINE SB16AD( DICO, JOBC, JOBO, JOBMR, WEIGHT, EQUIL, ORDSEL,
-     $                   N, M, P, NC, NCR, ALPHA, A, LDA, B, LDB,
-     $                   C, LDC, D, LDD, AC, LDAC, BC, LDBC, CC, LDCC,
-     $                   DC, LDDC, NCS, HSVC, TOL1, TOL2, IWORK, DWORK,
-     $                   LDWORK, IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute a reduced order controller (Acr,Bcr,Ccr,Dcr) for an
-C     original state-space controller representation (Ac,Bc,Cc,Dc) by
-C     using the frequency-weighted square-root or balancing-free
-C     square-root Balance & Truncate (B&T) or Singular Perturbation
-C     Approximation (SPA) model reduction methods. The algorithm tries
-C     to minimize the norm of the frequency-weighted error
-C
-C           ||V*(K-Kr)*W||
-C
-C     where K and Kr are the transfer-function matrices of the original
-C     and reduced order controllers, respectively. V and W are special
-C     frequency-weighting transfer-function matrices constructed
-C     to enforce closed-loop stability and/or closed-loop performance.
-C     If G is the transfer-function matrix of the open-loop system, then
-C     the following weightings V and W can be used:
-C                      -1
-C      (a)   V = (I-G*K) *G, W = I - to enforce closed-loop stability;
-C                              -1
-C      (b)   V = I,  W = (I-G*K) *G - to enforce closed-loop stability;
-C                      -1              -1
-C      (c)   V = (I-G*K) *G, W = (I-G*K)  - to enforce closed-loop
-C            stability and performance.
-C
-C     G has the state space representation (A,B,C,D).
-C     If K is unstable, only the ALPHA-stable part of K is reduced.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the original controller as follows:
-C             = 'C':  continuous-time controller;
-C             = 'D':  discrete-time controller.
-C
-C     JOBC    CHARACTER*1
-C             Specifies the choice of frequency-weighted controllability
-C             Grammian as follows:
-C             = 'S': choice corresponding to standard Enns' method [1];
-C             = 'E': choice corresponding to the stability enhanced
-C                    modified Enns' method of [2].
-C
-C     JOBO    CHARACTER*1
-C             Specifies the choice of frequency-weighted observability
-C             Grammian as follows:
-C             = 'S': choice corresponding to standard Enns' method [1];
-C             = 'E': choice corresponding to the stability enhanced
-C                    modified combination method of [2].
-C
-C     JOBMR   CHARACTER*1
-C             Specifies the model reduction approach to be used
-C             as follows:
-C             = 'B':  use the square-root B&T method;
-C             = 'F':  use the balancing-free square-root B&T method;
-C             = 'S':  use the square-root SPA method;
-C             = 'P':  use the balancing-free square-root SPA method.
-C
-C     WEIGHT  CHARACTER*1
-C             Specifies the type of frequency-weighting, as follows:
-C             = 'N':  no weightings are used (V = I, W = I);
-C             = 'O':  stability enforcing left (output) weighting
-C                               -1
-C                     V = (I-G*K) *G is used (W = I);
-C             = 'I':  stability enforcing right (input) weighting
-C                               -1
-C                     W = (I-G*K) *G is used (V = I);
-C             = 'P':  stability and performance enforcing weightings
-C                               -1                -1
-C                     V = (I-G*K) *G ,  W = (I-G*K)  are used.
-C
-C     EQUIL   CHARACTER*1
-C             Specifies whether the user wishes to preliminarily
-C             equilibrate the triplets (A,B,C) and (Ac,Bc,Cc) as
-C             follows:
-C             = 'S':  perform equilibration (scaling);
-C             = 'N':  do not perform equilibration.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting order NCR is fixed;
-C             = 'A':  the resulting order NCR is automatically
-C                     determined on basis of the given tolerance TOL1.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the open-loop system state-space
-C             representation, i.e., the order of the matrix A.  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     NC      (input) INTEGER
-C             The order of the controller state-space representation,
-C             i.e., the order of the matrix AC.  NC >= 0.
-C
-C     NCR     (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NCR is the desired order of
-C             the resulting reduced order controller.  0 <= NCR <= NC.
-C             On exit, if INFO = 0, NCR is the order of the resulting
-C             reduced order controller. For a controller with NCU
-C             ALPHA-unstable eigenvalues and NCS ALPHA-stable
-C             eigenvalues (NCU+NCS = NC), NCR is set as follows:
-C             if ORDSEL = 'F', NCR is equal to
-C             NCU+MIN(MAX(0,NCR-NCU),NCMIN), where NCR is the desired
-C             order on entry, NCMIN is the number of frequency-weighted
-C             Hankel singular values greater than NCS*EPS*S1, EPS is the
-C             machine precision (see LAPACK Library Routine DLAMCH) and
-C             S1 is the largest Hankel singular value (computed in
-C             HSVC(1)); NCR can be further reduced to ensure
-C             HSVC(NCR-NCU) > HSVC(NCR+1-NCU);
-C             if ORDSEL = 'A', NCR is the sum of NCU and the number of
-C             Hankel singular values greater than MAX(TOL1,NCS*EPS*S1).
-C
-C     ALPHA   (input) DOUBLE PRECISION
-C             Specifies the ALPHA-stability boundary for the eigenvalues
-C             of the state dynamics matrix AC. For a continuous-time
-C             controller (DICO = 'C'), ALPHA <= 0 is the boundary value
-C             for the real parts of eigenvalues; for a discrete-time
-C             controller (DICO = 'D'), 0 <= ALPHA <= 1 represents the
-C             boundary value for the moduli of eigenvalues.
-C             The ALPHA-stability domain does not include the boundary.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the state dynamics matrix A of the open-loop
-C             system.
-C             On exit, if INFO = 0 and EQUIL = 'S', the leading N-by-N
-C             part of this array contains the scaled state dynamics
-C             matrix of the open-loop system.
-C             If EQUIL = 'N', this array is unchanged on exit.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input/state matrix B of the open-loop system.
-C             On exit, if INFO = 0 and EQUIL = 'S', the leading N-by-M
-C             part of this array contains the scaled input/state matrix
-C             of the open-loop system.
-C             If EQUIL = 'N', this array is unchanged on exit.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the state/output matrix C of the open-loop system.
-C             On exit, if INFO = 0 and EQUIL = 'S', the leading P-by-N
-C             part of this array contains the scaled state/output matrix
-C             of the open-loop system.
-C             If EQUIL = 'N', this array is unchanged on exit.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input) DOUBLE PRECISION array, dimension (LDD,M)
-C             The leading P-by-M part of this array must contain the
-C             input/output matrix D of the open-loop system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     AC      (input/output) DOUBLE PRECISION array, dimension (LDAC,NC)
-C             On entry, the leading NC-by-NC part of this array must
-C             contain the state dynamics matrix Ac of the original
-C             controller.
-C             On exit, if INFO = 0, the leading NCR-by-NCR part of this
-C             array contains the state dynamics matrix Acr of the
-C             reduced controller. The resulting Ac has a
-C             block-diagonal form with two blocks.
-C             For a system with NCU ALPHA-unstable eigenvalues and
-C             NCS ALPHA-stable eigenvalues (NCU+NCS = NC), the leading
-C             NCU-by-NCU block contains the unreduced part of Ac
-C             corresponding to the ALPHA-unstable eigenvalues.
-C             The trailing (NCR+NCS-NC)-by-(NCR+NCS-NC) block contains
-C             the reduced part of Ac corresponding to ALPHA-stable
-C             eigenvalues.
-C
-C     LDAC    INTEGER
-C             The leading dimension of array AC.  LDAC >= MAX(1,NC).
-C
-C     BC      (input/output) DOUBLE PRECISION array, dimension (LDBC,P)
-C             On entry, the leading NC-by-P part of this array must
-C             contain the input/state matrix Bc of the original
-C             controller.
-C             On exit, if INFO = 0, the leading NCR-by-P part of this
-C             array contains the input/state matrix Bcr of the reduced
-C             controller.
-C
-C     LDBC    INTEGER
-C             The leading dimension of array BC.  LDBC >= MAX(1,NC).
-C
-C     CC      (input/output) DOUBLE PRECISION array, dimension (LDCC,NC)
-C             On entry, the leading M-by-NC part of this array must
-C             contain the state/output matrix Cc of the original
-C             controller.
-C             On exit, if INFO = 0, the leading M-by-NCR part of this
-C             array contains the state/output matrix Ccr of the reduced
-C             controller.
-C
-C     LDCC    INTEGER
-C             The leading dimension of array CC.  LDCC >= MAX(1,M).
-C
-C     DC      (input/output) DOUBLE PRECISION array, dimension (LDDC,P)
-C             On entry, the leading M-by-P part of this array must
-C             contain the input/output matrix Dc of the original
-C             controller.
-C             On exit, if INFO = 0, the leading M-by-P part of this
-C             array contains the input/output matrix Dcr of the reduced
-C             controller.
-C
-C     LDDC    INTEGER
-C             The leading dimension of array DC.  LDDC >= MAX(1,M).
-C
-C     NCS     (output) INTEGER
-C             The dimension of the ALPHA-stable part of the controller.
-C
-C     HSVC    (output) DOUBLE PRECISION array, dimension (NC)
-C             If INFO = 0, the leading NCS elements of this array
-C             contain the frequency-weighted Hankel singular values,
-C             ordered decreasingly, of the ALPHA-stable part of the
-C             controller.
-C
-C     Tolerances
-C
-C     TOL1    DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL1 contains the tolerance for
-C             determining the order of the reduced controller.
-C             For model reduction, the recommended value is
-C             TOL1 = c*S1, where c is a constant in the
-C             interval [0.00001,0.001], and S1 is the largest
-C             frequency-weighted Hankel singular value of the
-C             ALPHA-stable part of the original controller
-C             (computed in HSVC(1)).
-C             If TOL1 <= 0 on entry, the used default value is
-C             TOL1 = NCS*EPS*S1, where NCS is the number of
-C             ALPHA-stable eigenvalues of Ac and EPS is the machine
-C             precision (see LAPACK Library Routine DLAMCH).
-C             If ORDSEL = 'F', the value of TOL1 is ignored.
-C
-C     TOL2    DOUBLE PRECISION
-C             The tolerance for determining the order of a minimal
-C             realization of the ALPHA-stable part of the given
-C             controller. The recommended value is TOL2 = NCS*EPS*S1.
-C             This value is used by default if TOL2 <= 0 on entry.
-C             If TOL2 > 0 and ORDSEL = 'A', then TOL2 <= TOL1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension MAX(1,LIWRK1,LIWRK2)
-C             LIWRK1 = 0,       if JOBMR  = 'B';
-C             LIWRK1 = NC,      if JOBMR  = 'F';
-C             LIWRK1 = 2*NC,    if JOBMR  = 'S' or 'P';
-C             LIWRK2 = 0,       if WEIGHT = 'N';
-C             LIWRK2 = 2*(M+P), if WEIGHT = 'O', 'I', or 'P'.
-C             On exit, if INFO = 0, IWORK(1) contains NCMIN, the order
-C             of the computed minimal realization of the stable part of
-C             the controller.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 2*NC*NC + MAX( 1, LFREQ, LSQRED ),
-C             where
-C             LFREQ = (N+NC)*(N+NC+2*M+2*P)+
-C                     MAX((N+NC)*(N+NC+MAX(N+NC,M,P)+7), (M+P)*(M+P+4))
-C                                      if WEIGHT = 'I' or 'O' or 'P';
-C             LFREQ  = NC*(MAX(M,P)+5) if WEIGHT = 'N' and EQUIL = 'N';
-C             LFREQ  = MAX(N,NC*(MAX(M,P)+5)) if WEIGHT = 'N' and
-C                                                EQUIL  = 'S';
-C             LSQRED = MAX( 1, 2*NC*NC+5*NC );
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NCR is greater
-C                   than NSMIN, the sum of the order of the
-C                   ALPHA-unstable part and the order of a minimal
-C                   realization of the ALPHA-stable part of the given
-C                   controller; in this case, the resulting NCR is set
-C                   equal to NSMIN;
-C             = 2:  with ORDSEL = 'F', the selected order NCR
-C                   corresponds to repeated singular values for the
-C                   ALPHA-stable part of the controller, which are
-C                   neither all included nor all excluded from the
-C                   reduced model; in this case, the resulting NCR is
-C                   automatically decreased to exclude all repeated
-C                   singular values;
-C             = 3:  with ORDSEL = 'F', the selected order NCR is less
-C                   than the order of the ALPHA-unstable part of the
-C                   given controller. In this case NCR is set equal to
-C                   the order of the ALPHA-unstable part.
-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 closed-loop system is not well-posed;
-C                   its feedthrough matrix is (numerically) singular;
-C             = 2:  the computation of the real Schur form of the
-C                   closed-loop state matrix failed;
-C             = 3:  the closed-loop state matrix is not stable;
-C             = 4:  the solution of a symmetric eigenproblem failed;
-C             = 5:  the computation of the ordered real Schur form of Ac
-C                   failed;
-C             = 6:  the separation of the ALPHA-stable/unstable
-C                   diagonal blocks failed because of very close
-C                   eigenvalues;
-C             = 7:  the computation of Hankel singular values failed.
-C
-C     METHOD
-C
-C     Let K be the transfer-function matrix of the original linear
-C     controller
-C
-C          d[xc(t)] = Ac*xc(t) + Bc*y(t)
-C          u(t)     = Cc*xc(t) + Dc*y(t),                      (1)
-C
-C     where d[xc(t)] is dxc(t)/dt for a continuous-time system and
-C     xc(t+1) for a discrete-time system. The subroutine SB16AD
-C     determines the matrices of a reduced order controller
-C
-C          d[z(t)] = Acr*z(t) + Bcr*y(t)
-C          u(t)    = Ccr*z(t) + Dcr*y(t),                      (2)
-C
-C     such that the corresponding transfer-function matrix Kr minimizes
-C     the norm of the frequency-weighted error
-C
-C             V*(K-Kr)*W,                                      (3)
-C
-C     where V and W are special stable transfer-function matrices
-C     chosen to enforce stability and/or performance of the closed-loop
-C     system [3] (see description of the parameter WEIGHT).
-C
-C     The following procedure is used to reduce K in conjunction
-C     with the frequency-weighted balancing approach of [2]
-C     (see also [3]):
-C
-C     1) Decompose additively K, of order NC, as
-C
-C          K = K1 + K2,
-C
-C        such that K1 has only ALPHA-stable poles and K2, of order NCU,
-C        has only ALPHA-unstable poles.
-C
-C     2) Compute for K1 a B&T or SPA frequency-weighted approximation
-C        K1r of order NCR-NCU using the frequency-weighted balancing
-C        approach of [1] in conjunction with accuracy enhancing
-C        techniques specified by the parameter JOBMR.
-C
-C     3) Assemble the reduced model Kr as
-C
-C           Kr = K1r + K2.
-C
-C     For the reduction of the ALPHA-stable part, several accuracy
-C     enhancing techniques can be employed (see [2] for details).
-C
-C     If JOBMR = 'B', the square-root B&T method of [1] is used.
-C
-C     If JOBMR = 'F', the balancing-free square-root version of the
-C     B&T method [1] is used.
-C
-C     If JOBMR = 'S', the square-root version of the SPA method [2,3]
-C     is used.
-C
-C     If JOBMR = 'P', the balancing-free square-root version of the
-C     SPA method [2,3] is used.
-C
-C     For each of these methods, two left and right truncation matrices
-C     are determined using the Cholesky factors of an input
-C     frequency-weighted controllability Grammian P and an output
-C     frequency-weighted observability Grammian Q.
-C     P and Q are determined as the leading NC-by-NC diagonal blocks
-C     of the controllability Grammian of K*W and of the
-C     observability Grammian of V*K. Special techniques developed in [2]
-C     are used to compute the Cholesky factors of P and Q directly
-C     (see also SLICOT Library routine SB16AY).
-C     The frequency-weighted Hankel singular values HSVC(1), ....,
-C     HSVC(NC) are computed as the square roots of the eigenvalues
-C     of the product P*Q.
-C
-C     REFERENCES
-C
-C     [1] Enns, D.
-C         Model reduction with balanced realizations: An error bound
-C         and a frequency weighted generalization.
-C         Proc. 23-th CDC, Las Vegas, pp. 127-132, 1984.
-C
-C     [2] Varga, A. and Anderson, B.D.O.
-C         Square-root balancing-free methods for frequency-weighted
-C         balancing related model reduction.
-C         (report in preparation)
-C
-C     [3] Anderson, B.D.O and Liu, Y.
-C         Controller reduction: concepts and approaches.
-C         IEEE Trans. Autom. Control, Vol. 34, pp. 802-812, 1989.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on accuracy enhancing square-root
-C     techniques.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, Sept. 2000.
-C     D. Sima, University of Bucharest, Sept. 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Sept.2000.
-C
-C     REVISIONS
-C
-C     A. Varga, Australian National University, Canberra, November 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Dec. 2000,
-C              Sep. 2001.
-C
-C     KEYWORDS
-C
-C     Controller reduction, frequency weighting, multivariable system,
-C     state-space model, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  C100, ONE, ZERO
-      PARAMETER         ( C100 = 100.0D0, ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, EQUIL, JOBC, JOBO, JOBMR, ORDSEL, WEIGHT
-      INTEGER           INFO, IWARN, LDA, LDAC, LDB, LDBC, LDC, LDCC,
-     $                  LDD, LDDC, LDWORK, M, N, NC, NCR, NCS, P
-      DOUBLE PRECISION  ALPHA, TOL1, TOL2
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), AC(LDAC,*), B(LDB,*), BC(LDBC,*),
-     $                  C(LDC,*), CC(LDCC,*), D(LDD,*), DC(LDDC,*),
-     $                  DWORK(*), HSVC(*)
-C     .. Local Scalars ..
-      LOGICAL           BAL, BTA, DISCR, FIXORD, FRWGHT, ISTAB, LEFTW,
-     $                  OSTAB, PERF, RIGHTW, SPA
-      INTEGER           IERR, IWARNL, KI, KR, KT, KTI, KU, KW, LW, MP,
-     $                  NCU, NCU1, NMR, NNC, NRA, WRKOPT
-      DOUBLE PRECISION  ALPWRK, MAXRED, SCALEC, SCALEO
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH
-      EXTERNAL          DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB09IX, SB16AY, TB01ID, TB01KD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         INT, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      DISCR  = LSAME( DICO,   'D' )
-      BTA    = LSAME( JOBMR,  'B' ) .OR. LSAME( JOBMR, 'F' )
-      SPA    = LSAME( JOBMR,  'S' ) .OR. LSAME( JOBMR, 'P' )
-      BAL    = LSAME( JOBMR,  'B' ) .OR. LSAME( JOBMR, 'S' )
-      FIXORD = LSAME( ORDSEL, 'F' )
-      ISTAB  = LSAME( WEIGHT, 'I' )
-      OSTAB  = LSAME( WEIGHT, 'O' )
-      PERF   = LSAME( WEIGHT, 'P' )
-      LEFTW  = OSTAB .OR. PERF
-      RIGHTW = ISTAB .OR. PERF
-      FRWGHT = LEFTW .OR. RIGHTW
-C
-      LW  = 1
-      NNC = N + NC
-      MP  = M + P
-      IF( FRWGHT ) THEN
-         LW = NNC*( NNC + 2*MP ) +
-     $        MAX( NNC*( NNC + MAX( NNC, M, P ) + 7 ), MP*( MP + 4 ) )
-      ELSE
-         LW = NC*( MAX( M, P ) + 5 )
-         IF ( LSAME( EQUIL, 'S' ) )
-     $      LW = MAX( N, LW )
-      END IF
-      LW = 2*NC*NC + MAX( 1, LW, NC*( 2*NC + 5 ) )
-C
-C     Check the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( LSAME( JOBC, 'S' ) .OR. LSAME( JOBC, 'E' ) ) )
-     $     THEN
-         INFO = -2
-      ELSE IF( .NOT.( LSAME( JOBO, 'S' ) .OR. LSAME( JOBO, 'E' ) ) )
-     $     THEN
-         INFO = -3
-      ELSE IF( .NOT. ( BTA .OR. SPA ) ) THEN
-         INFO = -4
-      ELSE IF( .NOT.( FRWGHT .OR. LSAME( WEIGHT, 'N' ) ) ) THEN
-         INFO = -5
-      ELSE IF( .NOT. ( LSAME( EQUIL, 'S' ) .OR.
-     $                 LSAME( EQUIL, 'N' ) ) ) THEN
-         INFO = -6
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -7
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -8
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -9
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -10
-      ELSE IF( NC.LT.0 ) THEN
-         INFO = -11
-      ELSE IF( FIXORD .AND. ( NCR.LT.0 .OR. NCR.GT.NC ) ) THEN
-         INFO = -12
-      ELSE IF( ( DISCR .AND. ( ALPHA.LT.ZERO .OR. ALPHA.GT.ONE ) ) .OR.
-     $    ( .NOT.DISCR .AND.   ALPHA.GT.ZERO ) ) THEN
-         INFO = -13
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -15
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -17
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -19
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -21
-      ELSE IF( LDAC.LT.MAX( 1, NC ) ) THEN
-         INFO = -23
-      ELSE IF( LDBC.LT.MAX( 1, NC ) ) THEN
-         INFO = -25
-      ELSE IF( LDCC.LT.MAX( 1, M  ) ) THEN
-         INFO = -27
-      ELSE IF( LDDC.LT.MAX( 1, M  ) ) THEN
-         INFO = -29
-      ELSE IF( TOL2.GT.ZERO .AND. .NOT.FIXORD .AND. TOL2.GT.TOL1 ) THEN
-         INFO = -33
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -36
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB16AD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( NC, M, P ).EQ.0 ) THEN
-         NCR = 0
-         NCS = 0
-         IWORK(1) = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      IF( LSAME( EQUIL, 'S' ) ) THEN
-C
-C        Scale simultaneously the matrices A, B and C and AC, BC and CC;
-C        A <- inv(T1)*A*T1, B <- inv(T1)*B and C <- C*T1, where T1 is a
-C        diagonal matrix;
-C        AC <- inv(T2)*AC*T2, BC <- inv(T2)*BC and CC <- CC*T2, where T2
-C        is a diagonal matrix.
-C
-C        Real workspace: need MAX(N,NC).
-C
-         MAXRED = C100
-         CALL TB01ID( 'All', N, M, P, MAXRED, A, LDA, B, LDB, C, LDC,
-     $                DWORK, INFO )
-         MAXRED = C100
-         CALL TB01ID( 'All', NC, P, M, MAXRED, AC, LDAC, BC, LDBC,
-     $                CC, LDCC, DWORK, INFO )
-      END IF
-C
-C     Correct the value of ALPHA to ensure stability.
-C
-      ALPWRK = ALPHA
-      IF( DISCR ) THEN
-         IF( ALPHA.EQ.ONE ) ALPWRK = ONE - SQRT( DLAMCH( 'E' ) )
-      ELSE
-         IF( ALPHA.EQ.ZERO ) ALPWRK = -SQRT( DLAMCH( 'E' ) )
-      END IF
-C
-C     Reduce Ac to a block-diagonal real Schur form, with the
-C     ALPHA-unstable part in the leading diagonal position, using a
-C     non-orthogonal similarity transformation, AC <- inv(T)*AC*T, and
-C     apply the transformation to BC and CC:
-C     BC <- inv(T)*BC and CC <- CC*T.
-C
-C     Workspace:  need   NC*(NC+5);
-C                 prefer larger.
-C
-      WRKOPT = 1
-      KU = 1
-      KR = KU + NC*NC
-      KI = KR + NC
-      KW = KI + NC
-C
-      CALL TB01KD( DICO, 'Unstable', 'General', NC, P, M, ALPWRK,
-     $             AC, LDAC, BC, LDBC, CC, LDCC, NCU, DWORK(KU), NC,
-     $             DWORK(KR), DWORK(KI), DWORK(KW), LDWORK-KW+1, IERR )
-C
-      IF( IERR.NE.0 ) THEN
-         IF( IERR.NE.3 ) THEN
-            INFO = 5
-         ELSE
-            INFO = 6
-         END IF
-         RETURN
-      END IF
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-      IWARNL = 0
-      NCS = NC - NCU
-      IF( FIXORD ) THEN
-         NRA = MAX( 0, NCR-NCU )
-         IF( NCR.LT.NCU )
-     $      IWARNL = 3
-      ELSE
-         NRA = 0
-      END IF
-C
-C     Finish if only unstable part is present.
-C
-      IF( NCS.EQ.0 ) THEN
-         NCR = NCU
-         IWORK(1) = 0
-         DWORK(1) = WRKOPT
-         RETURN
-      END IF
-C
-C     Allocate working storage.
-C
-      KT  = 1
-      KTI = KT  + NC*NC
-      KW  = KTI + NC*NC
-C
-C     Compute in DWORK(KTI) and DWORK(KT) the Cholesky factors S and R
-C     of the frequency-weighted controllability and observability
-C     Grammians, respectively.
-C
-C     Real workspace:  need  2*NC*NC + MAX( 1, LFREQ ),
-C                      where
-C                      LFREQ = (N+NC)*(N+NC+2*M+2*P)+
-C                              MAX((N+NC)*(N+NC+MAX(N+NC,M,P)+7),
-C                                  (M+P)*(M+P+4))
-C                                         if WEIGHT = 'I' or 'O' or 'P';
-C                      LFREQ = NCS*(MAX(M,P)+5) if WEIGHT = 'N';
-C                      prefer larger.
-C     Integer workspace:      2*(M+P) if WEIGHT = 'I' or 'O' or 'P';
-C                             0,      if WEIGHT = 'N'.
-C
-      CALL SB16AY( DICO, JOBC, JOBO, WEIGHT, N, M, P, NC, NCS,
-     $             A, LDA, B, LDB, C, LDC, D, LDD,
-     $             AC, LDAC, BC, LDBC, CC, LDCC, DC, LDDC,
-     $             SCALEC, SCALEO, DWORK(KTI), NC, DWORK(KT), NC,
-     $             IWORK, DWORK(KW), LDWORK-KW+1, INFO )
-      IF( INFO.NE.0 )
-     $   RETURN
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Compute a BTA or SPA of the stable part.
-C     Real workspace:  need   2*NC*NC + MAX( 1, 2*NC*NC+5*NC,
-C                                               NC*MAX(M,P) );
-C                      prefer larger.
-C     Integer workspace:      0,     if JOBMR = 'B';
-C                             NC,    if JOBMR = 'F';
-C                             2*NC,  if JOBMR = 'S' or 'P'.
-C
-      NCU1 = NCU + 1
-      CALL AB09IX( DICO, JOBMR, 'Schur', ORDSEL, NCS, P, M, NRA, SCALEC,
-     $             SCALEO, AC(NCU1,NCU1), LDAC, BC(NCU1,1), LDBC,
-     $             CC(1,NCU1), LDCC, DC, LDDC, DWORK(KTI), NC,
-     $             DWORK(KT), NC, NMR, HSVC, TOL1, TOL2, IWORK,
-     $             DWORK(KW), LDWORK-KW+1, IWARN, IERR )
-      IWARN = MAX( IWARN, IWARNL )
-      IF( IERR.NE.0 ) THEN
-         INFO = 7
-         RETURN
-      END IF
-      NCR = NRA + NCU
-      IWORK(1) = NMR
-C
-      DWORK(1) = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-      RETURN
-C *** Last line of SB16AD ***
-      END
--- a/extra/control-devel/src/SB16AY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,909 +0,0 @@
-      SUBROUTINE SB16AY( DICO, JOBC, JOBO, WEIGHT, N, M, P, NC, NCS,
-     $                   A, LDA, B, LDB, C, LDC, D, LDD,
-     $                   AC, LDAC, BC, LDBC, CC, LDCC, DC, LDDC,
-     $                   SCALEC, SCALEO, S, LDS, R, LDR,
-     $                   IWORK, DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute for given state-space representations (A,B,C,D) and
-C     (Ac,Bc,Cc,Dc) of the transfer-function matrices of the
-C     open-loop system G and feedback controller K, respectively,
-C     the Cholesky factors of the frequency-weighted
-C     controllability and observability Grammians corresponding
-C     to a frequency-weighted model reduction problem.
-C     The controller must stabilize the closed-loop system.
-C     The state matrix Ac must be in a block-diagonal real Schur form
-C     Ac = diag(Ac1,Ac2), where Ac1 contains the unstable eigenvalues
-C     of Ac and Ac2 contains the stable eigenvalues of Ac.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the systems as follows:
-C             = 'C':  G and K are continuous-time systems;
-C             = 'D':  G and K are discrete-time systems.
-C
-C     JOBC    CHARACTER*1
-C             Specifies the choice of frequency-weighted controllability
-C             Grammian as follows:
-C             = 'S': choice corresponding to standard Enns' method [1];
-C             = 'E': choice corresponding to the stability enhanced
-C                    modified Enns' method of [2].
-C
-C     JOBO    CHARACTER*1
-C             Specifies the choice of frequency-weighted observability
-C             Grammian as follows:
-C             = 'S': choice corresponding to standard Enns' method [1];
-C             = 'E': choice corresponding to the stability enhanced
-C                    modified combination method of [2].
-C
-C     WEIGHT  CHARACTER*1
-C             Specifies the type of frequency-weighting, as follows:
-C             = 'N':  no weightings are used (V = I, W = I);
-C             = 'O':  stability enforcing left (output) weighting
-C                               -1
-C                     V = (I-G*K) *G is used (W = I);
-C             = 'I':  stability enforcing right (input) weighting
-C                               -1
-C                     W = (I-G*K) *G is used (V = I);
-C             = 'P':  stability and performance enforcing weightings
-C                               -1                -1
-C                     V = (I-G*K) *G ,  W = (I-G*K)  are used.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the open-loop system state-space
-C             representation, i.e., the order of the matrix A.  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     NC      (input) INTEGER
-C             The order of the controller state-space representation,
-C             i.e., the order of the matrix AC.  NC >= 0.
-C
-C     NCS     (input) INTEGER
-C             The dimension of the stable part of the controller, i.e.,
-C             the order of matrix Ac2.  NC >= NCS >= 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             state matrix A of the system with the transfer-function
-C             matrix G.
-C
-C     LDA     INTEGER
-C             The leading dimension of 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             input/state matrix B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input) DOUBLE PRECISION array, dimension (LDC,N)
-C             The leading P-by-N part of this array must contain the
-C             state/output matrix C.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input) DOUBLE PRECISION array, dimension (LDD,M)
-C             The leading P-by-M part of this array must contain the
-C             input/output matrix D of the open-loop system.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.  LDD >= MAX(1,P).
-C
-C     AC      (input) DOUBLE PRECISION array, dimension (LDAC,NC)
-C             The leading NC-by-NC part of this array must contain
-C             the state dynamics matrix Ac of the controller in a
-C             block diagonal real Schur form Ac = diag(Ac1,Ac2), where
-C             Ac1 is (NC-NCS)-by-(NC-NCS) and contains the unstable
-C             eigenvalues of Ac, and Ac2 is NCS-by-NCS and contains
-C             the stable eigenvalues of Ac.
-C
-C     LDAC    INTEGER
-C             The leading dimension of array AC.  LDAC >= MAX(1,NC).
-C
-C     BC      (input) DOUBLE PRECISION array, dimension (LDBC,P)
-C             The leading NC-by-P part of this array must contain
-C             the input/state matrix Bc of the controller.
-C
-C     LDBC    INTEGER
-C             The leading dimension of array BC.  LDBC >= MAX(1,NC).
-C
-C     CC      (input) DOUBLE PRECISION array, dimension (LDCC,NC)
-C             The leading M-by-NC part of this array must contain
-C             the state/output matrix Cc of the controller.
-C
-C     LDCC    INTEGER
-C             The leading dimension of array CC.  LDCC >= MAX(1,M).
-C
-C     DC      (input) DOUBLE PRECISION array, dimension (LDDC,P)
-C             The leading M-by-P part of this array must contain
-C             the input/output matrix Dc of the controller.
-C
-C     LDDC    INTEGER
-C             The leading dimension of array DC.  LDDC >= MAX(1,M).
-C
-C     SCALEC  (output) DOUBLE PRECISION
-C             Scaling factor for the controllability Grammian.
-C             See METHOD.
-C
-C     SCALEO  (output) DOUBLE PRECISION
-C             Scaling factor for the observability Grammian. See METHOD.
-C
-C     S       (output) DOUBLE PRECISION array, dimension (LDS,NCS)
-C             The leading NCS-by-NCS upper triangular part of this array
-C             contains the Cholesky factor S of the frequency-weighted
-C             controllability Grammian P = S*S'. See METHOD.
-C
-C     LDS     INTEGER
-C             The leading dimension of array S.  LDS >= MAX(1,NCS).
-C
-C     R       (output) DOUBLE PRECISION array, dimension (LDR,NCS)
-C             The leading NCS-by-NCS upper triangular part of this array
-C             contains the Cholesky factor R of the frequency-weighted
-C             observability Grammian Q = R'*R. See METHOD.
-C
-C     LDR     INTEGER
-C             The leading dimension of array R.  LDR >= MAX(1,NCS).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension MAX(LIWRK)
-C             LIWRK = 0,       if WEIGHT = 'N';
-C             LIWRK = 2(M+P),  if WEIGHT = 'O', 'I', or 'P'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX( 1, LFREQ ),
-C             where
-C             LFREQ = (N+NC)*(N+NC+2*M+2*P)+
-C                     MAX((N+NC)*(N+NC+MAX(N+NC,M,P)+7), (M+P)*(M+P+4))
-C                                      if WEIGHT = 'I' or 'O' or 'P';
-C             LFREQ  = NCS*(MAX(M,P)+5) if WEIGHT = 'N'.
-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:  the closed-loop system is not well-posed;
-C                   its feedthrough matrix is (numerically) singular;
-C             = 2:  the computation of the real Schur form of the
-C                   closed-loop state matrix failed;
-C             = 3:  the closed-loop state matrix is not stable;
-C             = 4:  the solution of a symmetric eigenproblem failed;
-C             = 5:  the NCS-by-NCS trailing part Ac2 of the state
-C                   matrix Ac is not stable or not in a real Schur form.
-C
-C     METHOD
-C
-C     If JOBC = 'S', the controllability Grammian P is determined as
-C     follows:
-C
-C     - if WEIGHT = 'O' or 'N', P satisfies for a continuous-time
-C       controller the Lyapunov equation
-C
-C            Ac2*P + P*Ac2' +  scalec^2*Bc*Bc' = 0
-C
-C       and for a discrete-time controller
-C
-C            Ac2*P*Ac2' - P +  scalec^2*Bc*Bc' = 0;
-C
-C     - if WEIGHT = 'I' or 'P', let Pi be the solution of the
-C       continuous-time Lyapunov equation
-C
-C            Ai*Pi + Pi*Ai' +  scalec^2*Bi*Bi' = 0
-C
-C       or of the discrete-time Lyapunov equation
-C
-C            Ai*Pi*Ai' - Pi +  scalec^2*Bi*Bi' = 0,
-C
-C       where Ai and Bi are the state and input matrices of a special
-C       state-space realization of the input frequency weight (see [2]);
-C       P results as the trailing NCS-by-NCS part of Pi partitioned as
-C
-C           Pi = ( *  * ).
-C                ( *  P )
-C
-C     If JOBC = 'E', a modified controllability Grammian P1 >= P is
-C     determined to guarantee stability for a modified Enns' method [2].
-C
-C     If JOBO = 'S', the observability Grammian Q is determined as
-C     follows:
-C
-C     - if WEIGHT = 'I' or 'N', Q satisfies for a continuous-time
-C       controller the Lyapunov equation
-C
-C            Ac2'*Q + Q*Ac2 +  scaleo^2*Cc'*Cc = 0
-C
-C       and for a discrete-time controller
-C
-C            Ac2'*Q*Ac2 - Q +  scaleo^2*Cc'*Cc = 0;
-C
-C     - if WEIGHT = 'O' or 'P', let Qo be the solution of the
-C       continuous-time Lyapunov equation
-C
-C            Ao'*Qo + Qo*Ao +  scaleo^2*Co'*Co = 0
-C
-C       or of the discrete-time Lyapunov equation
-C
-C            Ao'*Qo*Ao - Qo +  scaleo^2*Co'*Co = 0,
-C
-C       where Ao and Co are the state and output matrices of a
-C       special state-space realization of the output frequency weight
-C       (see [2]); if WEIGHT = 'O', Q results as the leading NCS-by-NCS
-C       part of Qo partitioned as
-C
-C           Qo = ( Q  * )
-C                ( *  * )
-C
-C       while if WEIGHT = 'P', Q results as the trailing NCS-by-NCS
-C       part of Qo partitioned as
-C
-C           Qo = ( *  * ).
-C                ( *  Q )
-C
-C     If JOBO = 'E', a modified observability Grammian Q1 >= Q is
-C     determined to guarantee stability for a modified Enns' method [2].
-C
-C     The routine computes directly the Cholesky factors S and R
-C     such that P = S*S' and Q = R'*R according to formulas
-C     developed in [2].
-C
-C     REFERENCES
-C
-C     [1] Enns, D.
-C         Model reduction with balanced realizations: An error bound
-C         and a frequency weighted generalization.
-C         Proc. CDC, Las Vegas, pp. 127-132, 1984.
-C
-C     [2] Varga, A. and Anderson, B.D.O.
-C         Frequency-weighted balancing related controller reduction.
-C         Proceedings of the 15th IFAC World Congress, July 21-26, 2002,
-C         Barcelona, Spain, Vol.15, Part 1, 2002-07-21.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, Australian National University, Canberra, November 2000.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Dec. 2000,
-C     May 2009.
-C     A. Varga, DLR Oberpfafenhofen, June 2001.
-C
-C
-C     KEYWORDS
-C
-C     Controller reduction, frequency weighting, multivariable system,
-C     state-space model, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION ZERO, ONE
-      PARAMETER        ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER        DICO, JOBC, JOBO, WEIGHT
-      INTEGER          INFO, LDA, LDAC, LDB, LDBC, LDC, LDCC, LDD, LDDC,
-     $                 LDR, LDS, LDWORK, M, N, NC, NCS, P
-      DOUBLE PRECISION SCALEC, SCALEO
-C     .. Array Arguments ..
-      INTEGER          IWORK(*)
-      DOUBLE PRECISION A(LDA,*), AC(LDAC,*), B(LDB,*), BC(LDBC,*),
-     $                 C(LDC,*), CC(LDCC,*), D(LDD,*), DC(LDDC,*),
-     $                 DWORK(*), R(LDR,*),   S(LDS,*)
-C     .. Local Scalars ..
-      CHARACTER        JOBFAC
-      LOGICAL          DISCR, FRWGHT, LEFTW, PERF, RIGHTW
-      INTEGER          I, IERR, J, JJ, KI, KL, KQ, KR, KTAU, KU, KW,
-     $                 KWA, KWB, KWC, KWD, LDU, LW, MBBAR, ME, MP,
-     $                 NCU, NCU1, NE, NNC, NNCU, PCBAR, PE, WRKOPT
-      DOUBLE PRECISION RCOND, T, TOL
-C     .. Local Arrays ..
-      DOUBLE PRECISION DUM(1)
-C     .. External Functions ..
-      LOGICAL          LSAME
-      DOUBLE PRECISION DLAMCH
-      EXTERNAL         DLAMCH, LSAME
-C     .. External Subroutines ..
-      EXTERNAL         AB05PD, AB05QD, AB07ND, DCOPY, DLACPY, DLASET,
-     $                 DSCAL, DSYEV, MB01WD, MB04OD, SB03OD, SB03OU,
-     $                 XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC        ABS, INT, MAX, MIN, SQRT
-C     .. Executable Statements ..
-C
-      DISCR  = LSAME( DICO,   'D' )
-      LEFTW  = LSAME( WEIGHT, 'O' )
-      RIGHTW = LSAME( WEIGHT, 'I' )
-      PERF   = LSAME( WEIGHT, 'P' )
-      FRWGHT = LEFTW .OR. RIGHTW .OR. PERF
-C
-      INFO = 0
-      NNC  = N + NC
-      MP   = M + P
-      IF( FRWGHT ) THEN
-         LW = NNC*( NNC + 2*MP ) +
-     $        MAX( NNC*( NNC + MAX( NNC, M, P ) + 7 ), MP*( MP + 4 ) )
-      ELSE
-         LW = NCS*( MAX( M, P ) + 5 )
-      END IF
-      LW = MAX( 1, LW )
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( LSAME( JOBC, 'S' ) .OR. LSAME( JOBC, 'E' ) ) )
-     $     THEN
-         INFO = -2
-      ELSE IF( .NOT.( LSAME( JOBO, 'S' ) .OR. LSAME( JOBO, 'E' ) ) )
-     $     THEN
-         INFO = -3
-      ELSE IF( .NOT.( FRWGHT .OR. LSAME( WEIGHT, 'N' ) ) ) THEN
-         INFO = -4
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( NC.LT.0 ) THEN
-         INFO = -8
-      ELSE IF( NCS.LT.0 .OR. NCS.GT.NC ) THEN
-         INFO = -9
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -13
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -15
-      ELSE IF( LDD.LT.MAX( 1, P ) ) THEN
-         INFO = -17
-      ELSE IF( LDAC.LT.MAX( 1, NC ) ) THEN
-         INFO = -19
-      ELSE IF( LDBC.LT.MAX( 1, NC ) ) THEN
-         INFO = -21
-      ELSE IF( LDCC.LT.MAX( 1, M ) ) THEN
-         INFO = -23
-      ELSE IF( LDDC.LT.MAX( 1, M ) ) THEN
-         INFO = -25
-      ELSE IF( LDS.LT.MAX( 1, NCS ) ) THEN
-         INFO = -29
-      ELSE IF( LDR.LT.MAX( 1, NCS ) ) THEN
-         INFO = -31
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -34
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB16AY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      SCALEC = ONE
-      SCALEO = ONE
-      IF( MIN( NCS, M, P ).EQ.0 ) THEN
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      WRKOPT = 1
-      NCU  = NC - NCS
-      NCU1 = NCU + 1
-C
-      IF( .NOT.PERF ) THEN
-C
-C        Compute the Grammians in the case of no weighting or
-C        one-sided weighting.
-C
-         IF( LEFTW .OR. LSAME( WEIGHT, 'N' ) ) THEN
-C
-C           Compute the standard controllability Grammian.
-C
-C           Solve for the Cholesky factor S of P, P = S*S',
-C           the continuous-time Lyapunov equation (if DICO = 'C')
-C
-C               Ac2*P + P*Ac2' +  scalec^2*Bc2*Bc2' = 0,
-C
-C           or the discrete-time Lyapunov equation (if DICO = 'D')
-C
-C               Ac2*P*Ac2' - P +  scalec^2*Bc2*Bc2' = 0,
-C
-C           where Bc2 is the matrix formed from the last NCS rows of Bc.
-C
-C           Workspace:  need   NCS*(P+5);
-C                              prefer larger.
-            KU   = 1
-            KTAU = KU + NCS*P
-            KW   = KTAU + NCS
-C
-            CALL DLACPY( 'Full', NCS, P, BC(NCU1,1), LDBC,
-     $                   DWORK(KU), NCS )
-            CALL SB03OU( DISCR, .TRUE., NCS, P, AC(NCU1,NCU1), LDAC,
-     $                   DWORK(KU), NCS, DWORK(KTAU), S, LDS, SCALEC,
-     $                   DWORK(KW), LDWORK-KW+1, IERR )
-            IF( IERR.NE.0 ) THEN
-               INFO = 5
-               RETURN
-            END IF
-            WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         END IF
-C
-         IF( RIGHTW .OR. LSAME( WEIGHT, 'N' ) ) THEN
-C
-C           Compute the standard observability Grammian.
-C
-C           Solve for the Cholesky factor R of Q, Q = R'*R,
-C           the continuous-time Lyapunov equation (if DICO = 'C')
-C
-C               Ac2'*Q + Q*Ac2  +  scaleo^2*Cc2'*Cc2 = 0,
-C
-C           or the discrete-time Lyapunov equation (if DICO = 'D')
-C
-C               Ac2'*Q*Ac2 - Q +  scaleo^2*Cc2'*Cc2 = 0,
-C
-C           where Cc2 is the matrix formed from the last NCS columns
-C           of Cc.
-C
-C           Workspace:  need   NCS*(M + 5);
-C                              prefer larger.
-            KU   = 1
-            KTAU = KU + M*NCS
-            KW   = KTAU + NCS
-C
-            CALL DLACPY( 'Full', M, NCS, CC(1,NCU1), LDCC,
-     $                   DWORK(KU), M )
-            CALL SB03OU( DISCR, .FALSE., NCS, M, AC(NCU1,NCU1), LDAC,
-     $                   DWORK(KU), M, DWORK(KTAU), R, LDR, SCALEO,
-     $                   DWORK(KW), LDWORK-KW+1, IERR )
-            IF( IERR.NE.0 ) THEN
-               INFO = 5
-               RETURN
-            END IF
-            WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         END IF
-C
-C        Finish if there are no weights.
-C
-         IF( LSAME( WEIGHT, 'N' ) ) THEN
-            DWORK(1) = WRKOPT
-            RETURN
-         END IF
-      END IF
-C
-      IF( FRWGHT ) THEN
-C
-C        Allocate working storage for computing the weights.
-C
-C        Real workspace:    need MAX(1,NNC*NNC+2*NNC*MP+MP*(MP+4));
-C        Integer workspace: need 2*MP.
-C
-         KWA = 1
-         KWB = KWA + NNC*NNC
-         KWC = KWB + NNC*MP
-         KWD = KWC + NNC*MP
-         KW  = KWD + MP*MP
-         KL  = KWD
-C
-         IF( LEFTW ) THEN
-C
-C           Build the extended matrices
-C
-C           Ao = ( Ac+Bc*inv(R)*D*Cc   Bc*inv(R)*C   ),
-C                (     B*inv(Rt)*Cc  A+B*Dc*inv(R)*C )
-C
-C           Co = ( -inv(R)*D*Cc  -inv(R)*C ) ,
-C
-C           where  R = I-D*Dc and Rt = I-Dc*D.
-C                             -1
-C           Method: Compute Ge  = ( Ge11 Ge12 ), where Ge = ( K   -Im ).
-C                                 ( Ge21 Ge22 )             ( -Ip  G  )
-C
-C                               -1
-C           Then  Ge11 = -(I-G*K) *G .
-C
-C           Construct first Ge = (  K  -Im ) such that the stable part
-C                                ( -Ip  G  )
-C           of K is in the leading position (to avoid updating of
-C           QR factorization).
-C
-            CALL DLASET( 'Full', M, P, ZERO, ZERO, DWORK(KWD), MP )
-            CALL AB05PD( 'N', NCS, P, M, NCU, ONE,
-     $                   AC(NCU1,NCU1), LDAC, BC(NCU1,1), LDBC,
-     $                   CC(1,NCU1), LDCC, DWORK(KWD), MP,
-     $                   AC, LDAC, BC, LDBC, CC, LDCC, DC, LDDC,
-     $                   NE, DWORK(KWA), NNC, DWORK(KWB), NNC,
-     $                   DWORK(KWC), MP, DWORK(KWD), MP, IERR )
-            CALL AB05QD( 'Over', NC, P, M, N, M, P, DWORK(KWA), NNC,
-     $                   DWORK(KWB), NNC, DWORK(KWC), MP, DWORK(KWD),
-     $                   MP, A, LDA, B, LDB, C, LDC, D, LDD,
-     $                   NE, ME, PE, DWORK(KWA), NNC, DWORK(KWB), NNC,
-     $                   DWORK(KWC), MP, DWORK(KWD), MP, IERR )
-            CALL DLASET( 'Full', M, M, ZERO, -ONE, DWORK(KWD+MP*P), MP )
-            CALL DLASET( 'Full', P, P, ZERO, -ONE, DWORK(KWD+M), MP )
-C
-         ELSE
-C
-C           Build the extended matrices
-C
-C           Ai = ( A+B*Dc*inv(R)*C   B*inv(Rt)*Cc   ) ,
-C                (   Bc*inv(R)*C  Ac+Bc*inv(R)*D*Cc )
-C
-C           Bi = ( B*Dc*inv(R)    B*inv(Rt)  ) ,
-C                ( Bc*inv(R)    Bc*D*inv(Rt) )
-C
-C           Ci = (  -inv(R)*C   -inv(R)*D*Cc ) , where
-C
-C           R = I-D*Dc and Rt = I-Dc*D.
-C
-C                             -1
-C           Method: Compute Ge  = ( Ge11 Ge12 ), where Ge = ( G   -Ip ).
-C                                 ( Ge21 Ge22 )             ( -Im  K  )
-C
-C                              -1                     -1
-C           Then Ge22 = -(I-G*K) *G and Ge21 = -(I-G*K) .
-C
-C           Construct first Ge = (  G  -Ip ).
-C                                ( -Im  K  )
-C
-            CALL AB05QD( 'N', N, M, P, NC, P, M, A, LDA, B, LDB, C, LDC,
-     $                   D, LDD, AC, LDAC, BC, LDBC, CC, LDCC, DC, LDDC,
-     $                   NE, ME, PE, DWORK(KWA), NNC, DWORK(KWB), NNC,
-     $                   DWORK(KWC), MP, DWORK(KWD), MP, IERR )
-            CALL DLASET( 'Full', P, P, ZERO, -ONE, DWORK(KWD+MP*M), MP )
-            CALL DLASET( 'Full', M, M, ZERO, -ONE, DWORK(KWD+P), MP )
-         END IF
-C                  -1
-C        Compute Ge   = ( Ge11 Ge12 ).
-C                       ( Ge21 Ge22 )
-C
-C        Additional real workspace: need 4*MP;
-C        Integer workspace:         need 2*MP.
-C
-         CALL AB07ND( NNC, MP, DWORK(KWA), NNC, DWORK(KWB), NNC,
-     $                DWORK(KWC), MP, DWORK(KWD), MP, RCOND,
-     $                IWORK, DWORK(KW), LDWORK-KW+1, IERR )
-         IF( IERR.NE.0 ) THEN
-            INFO = 1
-            RETURN
-         END IF
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C                     -1   ( A1 | B1  B2  )
-C        Partition  Ge   = (--------------) and select appropriate
-C                          ( C1 | D11 D12 )
-C                          ( C2 | D21 D22 )
-C
-C        pointers to matrices and column dimensions to define weights.
-C
-         IF( RIGHTW ) THEN
-C
-C           Define B2 for Ge22.
-C
-            ME  = M
-            KWB = KWB + NNC*P
-         ELSE IF( PERF ) THEN
-C
-C           Define B1 and C2 for Ge21.
-C
-            ME  = P
-            KWC = KWC + M
-         END IF
-      END IF
-C
-      IF( LEFTW .OR. PERF ) THEN
-C
-C        Compute the frequency-weighted observability Grammian.
-C
-C        Solve for the Cholesky factor Ro of Qo, Qo = Ro'*Ro,
-C        the continuous-time Lyapunov equation (if DICO = 'C')
-C
-C            Ao'*Qo + Qo*Ao  +  scaleo^2*Co'*Co = 0,
-C
-C        or the discrete-time Lyapunov equation (if DICO = 'D')
-C
-C            Ao'*Qo*Ao - Qo +  scaleo^2*Co'*Co = 0.
-C
-C        Additional workspace:  need   NNC*(NNC+MAX(NNC,P)+7);
-C                               prefer larger.
-C
-         LDU = MAX( NNC, P )
-         KU  = KL
-         KQ  = KU + NNC*LDU
-         KR  = KQ + NNC*NNC
-         KI  = KR + NNC
-         KW  = KI + NNC
-C
-         JOBFAC = 'N'
-         CALL DLACPY( 'Full', P, NNC, DWORK(KWC), MP, DWORK(KU), LDU )
-         CALL SB03OD( DICO, JOBFAC, 'No-transpose', NNC, P,
-     $                DWORK(KWA), NNC, DWORK(KQ), NNC, DWORK(KU), LDU,
-     $                SCALEO, DWORK(KR), DWORK(KI), DWORK(KW),
-     $                LDWORK-KW+1, IERR )
-         IF( IERR.NE.0 ) THEN
-            IF( IERR.EQ.6 ) THEN
-               INFO = 2
-            ELSE
-               INFO = 3
-            END IF
-            RETURN
-         END IF
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C        Partition Ro as Ro = ( R11 R12 ).
-C                             (  0  R22 )
-C
-         IF( LEFTW ) THEN
-C
-C           R = R11 (NCS-by-NCS).
-C
-            CALL DLACPY( 'Upper', NCS, NCS, DWORK(KU), LDU, R, LDR )
-         ELSE
-C
-C           Compute R such that R'*R = R22'*R22 + R12'*R12, where
-C           R22 is NCS-by-NCS and R12 is (N+NCU)-by-NCS.
-C           R22 corresponds to the stable part of the controller.
-C
-            NNCU = N + NCU
-            CALL DLACPY( 'Upper', NCS, NCS, DWORK(KU+(LDU+1)*NNCU), LDU,
-     $                   R, LDR )
-            KTAU = KU
-            CALL MB04OD( 'Full', NCS, 0, NNCU, R, LDR,
-     $                   DWORK(KU+LDU*NNCU), LDU, DUM, 1, DUM, 1,
-     $                   DWORK(KTAU), DWORK(KW) )
-C
-            DO 10 J = 1, NCS
-               IF( R(J,J).LT.ZERO )
-     $            CALL DSCAL( NCS-J+1, -ONE, R(J,J), LDR )
-   10       CONTINUE
-         END IF
-      END IF
-C
-      IF( RIGHTW .OR. PERF ) THEN
-C
-C        Compute the frequency-weighted controllability Grammian.
-C
-C        Solve for the Cholesky factor Si of Pi, Pi = Si*Si',
-C        the continuous-time Lyapunov equation (if DICO = 'C')
-C
-C            Ai*Pi + Pi*Ai' +  scalec^2*Bi*Bi' = 0,
-C
-C        or the discrete-time Lyapunov equation (if DICO = 'D')
-C
-C            Ai*Pi*Ai' - Pi +  scalec^2*Bi*Bi' = 0.
-C
-C        Additional workspace:  need   NNC*(NNC+MAX(NNC,P,M)+7);
-C                               prefer larger.
-C
-         KU = KL
-         KQ = KU + NNC*MAX( NNC, ME )
-         KR = KQ + NNC*NNC
-         KI = KR + NNC
-         KW = KI + NNC
-C
-         CALL DLACPY( 'Full', NNC, ME, DWORK(KWB), NNC, DWORK(KU), NNC )
-         JOBFAC = 'F'
-         IF( RIGHTW ) JOBFAC = 'N'
-         CALL SB03OD( DICO, JOBFAC, 'Transpose', NNC, ME,
-     $                DWORK(KWA), NNC, DWORK(KQ), NNC, DWORK(KU), NNC,
-     $                SCALEC, DWORK(KR), DWORK(KI), DWORK(KW),
-     $                LDWORK-KW+1, IERR )
-         IF( IERR.NE.0 ) THEN
-            IF( IERR.EQ.6 ) THEN
-               INFO = 2
-            ELSE
-               INFO = 3
-            END IF
-            RETURN
-         END IF
-         WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C        Partition Si as Si = ( S11 S12 ) with S22 NCS-by-NCS and
-C                             (  0  S22 )
-C        set S = S22.
-C
-         NNCU = N + NCU
-         CALL DLACPY( 'Upper', NCS, NCS, DWORK(KU+(NNC+1)*NNCU), NNC,
-     $                S, LDS )
-      END IF
-C
-      KU = 1
-      IF( LEFTW .OR. PERF ) THEN
-         IF( LSAME( JOBO, 'E' ) ) THEN
-C
-C           Form Y = -Ac2'*(R'*R)-(R'*R)*Ac2 if DICO = 'C', or
-C                Y = -Ac2'*(R'*R)*Ac2+(R'*R) if DICO = 'D'.
-C
-C           Workspace:  need   2*NCS*NCS.
-C
-            CALL DLACPY( 'Upper', NCS, NCS, R, LDR, DWORK(KU), NCS )
-            CALL DLACPY( 'Full', NCS, NCS, AC(NCU1,NCU1), LDAC,
-     $                   DWORK(KU+NCS*NCS), NCS )
-            CALL MB01WD( DICO, 'Upper', 'No-transpose', 'Hessenberg',
-     $                   NCS, -ONE, ZERO, R, LDR, DWORK(KU+NCS*NCS),
-     $                   NCS, DWORK(KU), NCS, IERR )
-C
-C           Compute the eigendecomposition of Y as Y = Z*Sigma*Z'.
-C
-            KW = KU + NCS
-            CALL DSYEV( 'Vectors', 'Upper', NCS, R, LDR, DWORK(KU),
-     $                  DWORK(KW), LDWORK-KW+1, IERR )
-            IF( IERR.GT.0 ) THEN
-               INFO = 4
-               RETURN
-            END IF
-            WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C           Partition Sigma = (Sigma1,Sigma2), such that
-C           Sigma1 <= 0, Sigma2 > 0.
-C           Partition correspondingly Z = [Z1 Z2].
-C
-            TOL = MAX( ABS( DWORK(KU) ), ABS( DWORK(KU+NCS-1) ) )
-     $            * DLAMCH( 'Epsilon')
-C                _
-C           Form Cc = [ sqrt(Sigma2)*Z2' ]
-C
-            PCBAR = 0
-            JJ = KU
-            DO 20 J = 1, NCS
-               IF( DWORK(JJ).GT.TOL ) THEN
-                  CALL DSCAL( NCS, SQRT( DWORK(JJ) ), R(1,J), 1 )
-                  CALL DCOPY( NCS, R(1,J), 1, DWORK(KW+PCBAR), NCS )
-                  PCBAR = PCBAR + 1
-               END IF
-               JJ = JJ + 1
-   20       CONTINUE
-C
-C           Solve for the Cholesky factor R of Q, Q = R'*R,
-C           the continuous-time Lyapunov equation (if DICO = 'C')
-C                                               _   _
-C                   Ac2'*Q + Q*Ac2  +  scaleo^2*Cc'*Cc = 0,
-C
-C           or the discrete-time Lyapunov equation (if DICO = 'D')
-C                                              _   _
-C                   Ac2'*Q*Ac2 - Q +  scaleo^2*Cc'*Cc = 0.
-C
-C           Workspace:  need   NCS*(NCS + 6);
-C                              prefer larger.
-C
-            KU   = KW
-            KTAU = KU + NCS*NCS
-            KW   = KTAU + NCS
-C
-            CALL SB03OU( DISCR, .FALSE., NCS, PCBAR, AC(NCU1,NCU1),
-     $                   LDAC, DWORK(KU), NCS, DWORK(KTAU), R, LDR, T,
-     $                   DWORK(KW), LDWORK-KW+1, IERR )
-            IF( IERR.NE.0 ) THEN
-               INFO = 5
-               RETURN
-            END IF
-            SCALEO = SCALEO*T
-            WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         END IF
-C
-      END IF
-C
-      IF( RIGHTW .OR. PERF ) THEN
-         IF( LSAME( JOBC, 'E' ) ) THEN
-C
-C           Form X = -A2c*(S*S')-(S*S')*Ac2' if DICO = 'C', or
-C                X = -Ac2*(S*S')*Ac2'+(S*S') if DICO = 'D'.
-C
-C           Workspace:  need   2*NCS*NCS.
-C
-            CALL DLACPY( 'Upper', NCS, NCS, S, LDS, DWORK(KU), NCS )
-            CALL DLACPY( 'Full', NCS, NCS, AC(NCU1,NCU1), LDAC,
-     $                   DWORK(KU+NCS*NCS), NCS )
-            CALL MB01WD( DICO, 'Upper', 'Transpose', 'Hessenberg', NCS,
-     $                   -ONE, ZERO, S, LDS, DWORK(KU+NCS*NCS), NCS,
-     $                   DWORK(KU), NCS, IERR )
-C
-C           Compute the eigendecomposition of X as X = Z*Sigma*Z'.
-C
-            KW = KU + NCS
-            CALL DSYEV( 'Vectors', 'Upper', NCS, S, LDS, DWORK(KU),
-     $                  DWORK(KW), LDWORK-KW+1, IERR )
-            IF( IERR.GT.0 ) THEN
-               INFO = 4
-               RETURN
-            END IF
-            WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C           Partition Sigma = (Sigma1,Sigma2), such that
-C           Sigma1 =< 0, Sigma2 > 0.
-C           Partition correspondingly Z = [Z1 Z2].
-C
-            TOL = MAX( ABS( DWORK(KU) ), ABS( DWORK(KU+NCS-1) ) )
-     $            * DLAMCH( 'Epsilon')
-C                _
-C           Form Bc = [ Z2*sqrt(Sigma2) ]
-C
-            MBBAR = 0
-            I  = KW
-            JJ = KU
-            DO 30 J = 1, NCS
-               IF( DWORK(JJ).GT.TOL ) THEN
-                  MBBAR = MBBAR + 1
-                  CALL DSCAL( NCS, SQRT( DWORK(JJ) ), S(1,J), 1 )
-                  CALL DCOPY( NCS, S(1,J), 1, DWORK(I), 1 )
-                  I = I + NCS
-               END IF
-               JJ = JJ + 1
-   30       CONTINUE
-C
-C           Solve for the Cholesky factor S of P, P = S*S',
-C           the continuous-time Lyapunov equation (if DICO = 'C')
-C                                               _  _
-C                   Ac2*P + P*Ac2'  +  scalec^2*Bc*Bc' = 0,
-C
-C           or the discrete-time Lyapunov equation (if DICO = 'D')
-C                                              _  _
-C                   Ac2*P*Ac2' - P +  scalec^2*Bc*Bc' = 0.
-C
-C           Workspace:  need   maximum NCS*(NCS + 6);
-C                       prefer larger.
-C
-            KU   = KW
-            KTAU = KU + MBBAR*NCS
-            KW   = KTAU + NCS
-C
-            CALL SB03OU( DISCR, .TRUE., NCS, MBBAR, AC(NCU1,NCU1), LDAC,
-     $                   DWORK(KU), NCS, DWORK(KTAU), S, LDS, T,
-     $                   DWORK(KW), LDWORK-KW+1, IERR )
-            IF( IERR.NE.0 ) THEN
-               INFO = 5
-               RETURN
-            END IF
-            SCALEC = SCALEC*T
-            WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-         END IF
-C
-      END IF
-C
-C     Save optimal workspace.
-C
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of SB16AY ***
-      END
--- a/extra/control-devel/src/SB16BD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,652 +0,0 @@
-      SUBROUTINE SB16BD( DICO, JOBD, JOBMR, JOBCF, EQUIL, ORDSEL,
-     $                   N, M, P, NCR, A, LDA, B, LDB, C, LDC, D, LDD,
-     $                   F, LDF, G, LDG, DC, LDDC, HSV, TOL1, TOL2,
-     $                   IWORK, DWORK, LDWORK, IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute, for a given open-loop model (A,B,C,D), and for
-C     given state feedback gain F and full observer gain G,
-C     such that A+B*F and A+G*C are stable, a reduced order
-C     controller model (Ac,Bc,Cc,Dc) using a coprime factorization
-C     based controller reduction approach. For reduction,
-C     either the square-root or the balancing-free square-root
-C     versions of the Balance & Truncate (B&T) or Singular Perturbation
-C     Approximation (SPA) model reduction methods are used in
-C     conjunction with stable coprime factorization techniques.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the open-loop system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     JOBD    CHARACTER*1
-C             Specifies whether or not a non-zero matrix D appears
-C             in the given state space model:
-C             = 'D':  D is present;
-C             = 'Z':  D is assumed a zero matrix.
-C
-C     JOBMR   CHARACTER*1
-C             Specifies the model reduction approach to be used
-C             as follows:
-C             = 'B':  use the square-root B&T method;
-C             = 'F':  use the balancing-free square-root B&T method;
-C             = 'S':  use the square-root SPA method;
-C             = 'P':  use the balancing-free square-root SPA method.
-C
-C     JOBCF   CHARACTER*1
-C             Specifies whether left or right coprime factorization is
-C             to be used as follows:
-C             = 'L':  use left coprime factorization;
-C             = 'R':  use right coprime factorization.
-C
-C     EQUIL   CHARACTER*1
-C             Specifies whether the user wishes to perform a
-C             preliminary equilibration before performing
-C             order reduction as follows:
-C             = 'S':  perform equilibration (scaling);
-C             = 'N':  do not perform equilibration.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting controller order NCR is fixed;
-C             = 'A':  the resulting controller order NCR is
-C                     automatically determined on basis of the given
-C                     tolerance TOL1.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the open-loop state-space representation,
-C             i.e., the order of the matrix A.  N >= 0.
-C             N also represents the order of the original state-feedback
-C             controller.
-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     NCR     (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NCR is the desired order of
-C             the resulting reduced order controller.  0 <= NCR <= N.
-C             On exit, if INFO = 0, NCR is the order of the resulting
-C             reduced order controller. NCR is set as follows:
-C             if ORDSEL = 'F', NCR is equal to MIN(NCR,NMIN), where NCR
-C             is the desired order on entry, and NMIN is the order of a
-C             minimal realization of an extended system Ge (see METHOD);
-C             NMIN is determined as the number of
-C             Hankel singular values greater than N*EPS*HNORM(Ge),
-C             where EPS is the machine precision (see LAPACK Library
-C             Routine DLAMCH) and HNORM(Ge) is the Hankel norm of the
-C             extended system (computed in HSV(1));
-C             if ORDSEL = 'A', NCR is equal to the number of Hankel
-C             singular values greater than MAX(TOL1,N*EPS*HNORM(Ge)).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the original state dynamics matrix A.
-C             On exit, if INFO = 0, the leading NCR-by-NCR part of this
-C             array contains the state dynamics matrix Ac of the reduced
-C             controller.
-C
-C     LDA     INTEGER
-C             The leading dimension of 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
-C             contain the original input/state matrix B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input) DOUBLE PRECISION array, dimension (LDC,N)
-C             The leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input) DOUBLE PRECISION array, dimension (LDD,M)
-C             If JOBD = 'D', the leading P-by-M part of this
-C             array must contain the system direct input/output
-C             transmission matrix D.
-C             The array D is not referenced if JOBD = 'Z'.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.
-C             LDD >= MAX(1,P), if JOBD = 'D';
-C             LDD >= 1,        if JOBD = 'Z'.
-C
-C     F       (input/output) DOUBLE PRECISION array, dimension (LDF,N)
-C             On entry, the leading M-by-N part of this array must
-C             contain a stabilizing state feedback matrix.
-C             On exit, if INFO = 0, the leading M-by-NCR part of this
-C             array contains the state/output matrix Cc of the reduced
-C             controller.
-C
-C     LDF     INTEGER
-C             The leading dimension of array F.  LDF >= MAX(1,M).
-C
-C     G       (input/output) DOUBLE PRECISION array, dimension (LDG,P)
-C             On entry, the leading N-by-P part of this array must
-C             contain a stabilizing observer gain matrix.
-C             On exit, if INFO = 0, the leading NCR-by-P part of this
-C             array contains the input/state matrix Bc of the reduced
-C             controller.
-C
-C     LDG     INTEGER
-C             The leading dimension of array G.  LDG >= MAX(1,N).
-C
-C     DC      (output) DOUBLE PRECISION array, dimension (LDDC,P)
-C             If INFO = 0, the leading M-by-P part of this array
-C             contains the input/output matrix Dc of the reduced
-C             controller.
-C
-C     LDDC    INTEGER
-C             The leading dimension of array DC.  LDDC >= MAX(1,M).
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, it contains the N Hankel singular values
-C             of the extended system ordered decreasingly (see METHOD).
-C
-C     Tolerances
-C
-C     TOL1    DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL1 contains the tolerance for
-C             determining the order of the reduced extended system.
-C             For model reduction, the recommended value is
-C             TOL1 = c*HNORM(Ge), where c is a constant in the
-C             interval [0.00001,0.001], and HNORM(Ge) is the
-C             Hankel norm of the extended system (computed in HSV(1)).
-C             The value TOL1 = N*EPS*HNORM(Ge) is used by default if
-C             TOL1 <= 0 on entry, where EPS is the machine precision
-C             (see LAPACK Library Routine DLAMCH).
-C             If ORDSEL = 'F', the value of TOL1 is ignored.
-C
-C     TOL2    DOUBLE PRECISION
-C             The tolerance for determining the order of a minimal
-C             realization of the coprime factorization controller
-C             (see METHOD). The recommended value is
-C             TOL2 = N*EPS*HNORM(Ge) (see METHOD).
-C             This value is used by default if TOL2 <= 0 on entry.
-C             If TOL2 > 0 and ORDSEL = 'A', then TOL2 <= TOL1.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (LIWORK)
-C             LIWORK = 0,         if ORDSEL = 'F' and NCR = N.
-C                                                 Otherwise,
-C             LIWORK = MAX(PM,M), if JOBCF = 'L',
-C             LIWORK = MAX(PM,P), if JOBCF = 'R', where
-C             PM = 0,             if JOBMR = 'B',
-C             PM = N,             if JOBMR = 'F',
-C             PM = MAX(1,2*N),    if JOBMR = 'S' or 'P'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= P*N, if ORDSEL = 'F' and NCR = N. Otherwise,
-C             LDWORK >= (N+M)*(M+P) + MAX(LWR,4*M), if JOBCF = 'L',
-C             LDWORK >= (N+P)*(M+P) + MAX(LWR,4*P), if JOBCF = 'R',
-C             where LWR = MAX(1,N*(2*N+MAX(N,M+P)+5)+N*(N+1)/2).
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NCR is
-C                   greater than the order of a minimal
-C                   realization of the controller.
-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 reduction of A+G*C to a real Schur form
-C                   failed;
-C             = 2:  the matrix A+G*C is not stable (if DICO = 'C'),
-C                   or not convergent (if DICO = 'D');
-C             = 3:  the computation of Hankel singular values failed;
-C             = 4:  the reduction of A+B*F to a real Schur form
-C                   failed;
-C             = 5:  the matrix A+B*F is not stable (if DICO = 'C'),
-C                   or not convergent (if DICO = 'D').
-C
-C     METHOD
-C
-C     Let be the linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t) + Du(t),                             (1)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system, and let Go(d) be the open-loop
-C     transfer-function matrix
-C                           -1
-C          Go(d) = C*(d*I-A) *B + D .
-C
-C     Let F and G be the state feedback and observer gain matrices,
-C     respectively, chosen so that A+B*F and A+G*C are stable matrices.
-C     The controller has a transfer-function matrix K(d) given by
-C                                        -1
-C          K(d) = F*(d*I-A-B*F-G*C-G*D*F) *G .
-C
-C     The closed-loop transfer-function matrix is given by
-C                                     -1
-C          Gcl(d) = Go(d)(I+K(d)Go(d)) .
-C
-C     K(d) can be expressed as a left coprime factorization (LCF),
-C                          -1
-C          K(d) = M_left(d) *N_left(d) ,
-C
-C     or as a right coprime factorization (RCF),
-C                                      -1
-C          K(d) = N_right(d)*M_right(d) ,
-C
-C     where M_left(d), N_left(d), N_right(d), and M_right(d) are
-C     stable transfer-function matrices.
-C
-C     The subroutine SB16BD determines the matrices of a reduced
-C     controller
-C
-C          d[z(t)] = Ac*z(t) + Bc*y(t)
-C          u(t)    = Cc*z(t) + Dc*y(t),                           (2)
-C
-C     with the transfer-function matrix Kr as follows:
-C
-C     (1) If JOBCF = 'L', the extended system
-C         Ge(d)  = [ N_left(d) M_left(d) ] is reduced to
-C         Ger(d) = [ N_leftr(d) M_leftr(d) ] by using either the
-C         B&T or SPA methods. The reduced order controller Kr(d)
-C         is computed as
-C                           -1
-C         Kr(d) = M_leftr(d) *N_leftr(d) ;
-C
-C     (2) If JOBCF = 'R', the extended system
-C         Ge(d) = [ N_right(d) ] is reduced to
-C                 [ M_right(d) ]
-C         Ger(d) = [ N_rightr(d) ] by using either the
-C                  [ M_rightr(d) ]
-C         B&T or SPA methods. The reduced order controller Kr(d)
-C         is computed as
-C                                         -1
-C         Kr(d) = N_rightr(d)* M_rightr(d) .
-C
-C     If ORDSEL = 'A', the order of the controller is determined by
-C     computing the number of Hankel singular values greater than
-C     the given tolerance TOL1. The Hankel singular values are
-C     the square roots of the eigenvalues of the product of
-C     the controllability and observability Grammians of the
-C     extended system Ge.
-C
-C     If JOBMR = 'B', the square-root B&T method of [1] is used.
-C
-C     If JOBMR = 'F', the balancing-free square-root version of the
-C     B&T method [1] is used.
-C
-C     If JOBMR = 'S', the square-root version of the SPA method [2,3]
-C     is used.
-C
-C     If JOBMR = 'P', the balancing-free square-root version of the
-C     SPA method [2,3] is used.
-C
-C     REFERENCES
-C
-C     [1] Tombs, M.S. and Postlethwaite, I.
-C         Truncated balanced realization of stable, non-minimal
-C         state-space systems.
-C         Int. J. Control, Vol. 46, pp. 1319-1330, 1987.
-C
-C     [2] Varga, A.
-C         Efficient minimal realization procedure based on balancing.
-C         Proc. of IMACS/IFAC Symp. MCTS, Lille, France, May 1991,
-C         A. El Moudui, P. Borne, S. G. Tzafestas (Eds.), Vol. 2,
-C         pp. 42-46, 1991.
-C
-C     [3] Varga, A.
-C         Coprime factors model reduction method based on square-root
-C         balancing-free techniques.
-C         System Analysis, Modelling and Simulation, Vol. 11,
-C         pp. 303-311, 1993.
-C
-C     [4] Liu, Y., Anderson, B.D.O. and Ly, O.L.
-C         Coprime factorization controller reduction with Bezout
-C         identity induced frequency weighting.
-C         Automatica, vol. 26, pp. 233-249, 1990.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on accuracy enhancing square-root or
-C     balancing-free square-root techniques.
-C                                         3
-C     The algorithms require less than 30N  floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, August 2000.
-C     D. Sima, University of Bucharest, August 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 2000.
-C
-C     REVISIONS
-C
-C     A. Varga, Australian National University, Canberra, November 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Dec. 2000,
-C              Aug. 2001.
-C
-C     KEYWORDS
-C
-C     Balancing, controller reduction, coprime factorization,
-C     minimal realization, multivariable system, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, EQUIL, JOBCF, JOBD, JOBMR, ORDSEL
-      INTEGER           INFO, IWARN, LDA, LDB, LDC, LDD, LDDC,
-     $                  LDF, LDG, LDWORK, M, N, NCR, P
-      DOUBLE PRECISION  TOL1, TOL2
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                  DC(LDDC,*), DWORK(*), F(LDF,*), G(LDG,*), HSV(*)
-C     .. Local Scalars ..
-      CHARACTER         JOB
-      LOGICAL           BAL, BTA, DISCR, FIXORD, LEFT, LEQUIL, SPA,
-     $                  WITHD
-      INTEGER           KBE, KCE, KDE, KW, LDBE, LDCE, LDDE, LW1, LW2,
-     $                  LWR, MAXMP, WRKOPT
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB09AD, AB09BD, DGEMM, DLACPY, DLASET, SB08GD,
-     $                  SB08HD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         INT, MAX, MIN
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      DISCR  = LSAME( DICO,   'D' )
-      WITHD  = LSAME( JOBD,   'D' )
-      BTA    = LSAME( JOBMR,  'B' ) .OR. LSAME( JOBMR, 'F' )
-      SPA    = LSAME( JOBMR,  'S' ) .OR. LSAME( JOBMR, 'P' )
-      BAL    = LSAME( JOBMR,  'B' ) .OR. LSAME( JOBMR, 'S' )
-      LEFT   = LSAME( JOBCF,  'L' )
-      LEQUIL = LSAME( EQUIL,  'S' )
-      FIXORD = LSAME( ORDSEL, 'F' )
-      MAXMP  = MAX( M, P )
-C
-      LWR = MAX( 1, N*( 2*N + MAX( N, M+P ) + 5 ) + ( N*(N+1) )/2 )
-      LW1 = (N+M)*(M+P) + MAX( LWR, 4*M )
-      LW2 = (N+P)*(M+P) + MAX( LWR, 4*P )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( WITHD .OR. LSAME( JOBD, 'Z' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( BTA .OR. SPA ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT. ( LEFT .OR. LSAME( JOBCF, 'R' ) ) ) THEN
-         INFO = -4
-      ELSE IF( .NOT. ( LEQUIL .OR. LSAME( EQUIL, 'N' ) ) ) THEN
-         INFO = -5
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -6
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -8
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -9
-      ELSE IF( FIXORD .AND. ( NCR.LT.0 .OR. NCR.GT.N ) ) THEN
-         INFO = -10
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -12
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -14
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -16
-      ELSE IF( LDD.LT.1 .OR. ( WITHD .AND. LDD.LT.P ) ) THEN
-         INFO = -18
-      ELSE IF( LDF.LT.MAX( 1, M ) ) THEN
-         INFO = -20
-      ELSE IF( LDG.LT.MAX( 1, N ) ) THEN
-         INFO = -22
-      ELSE IF( LDDC.LT.MAX( 1, M ) ) THEN
-         INFO = -24
-      ELSE IF( .NOT.FIXORD .AND. TOL2.GT.ZERO .AND. TOL2.GT.TOL1 ) THEN
-         INFO = -27
-      ELSE IF( ( ( .NOT.FIXORD .OR. NCR.LT.N ) .AND.
-     $         ( ( LEFT .AND. LDWORK.LT.LW1 ) ) .OR.
-     $      ( .NOT.LEFT .AND. LDWORK.LT.LW2 ) ) .OR.
-     $      ( FIXORD .AND. NCR.EQ.N .AND. LDWORK.LT.P*N ) ) THEN
-         INFO = -30
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB16BD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 .OR.
-     $    ( FIXORD .AND. BTA .AND. NCR.EQ.0 ) ) THEN
-         NCR = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      IF( NCR.EQ.N ) THEN
-C
-C        Form the controller state matrix,
-C        Ac = A + B*F + G*C + G*D*F = A + B*F + G*(C+D*F) .
-C        Real workspace:    need  P*N.
-C        Integer workspace: need  0.
-C
-         CALL DLACPY( 'Full', P, N, C, LDC, DWORK, P )
-         IF( WITHD ) CALL DGEMM( 'NoTranspose', 'NoTranspose', P, N, M,
-     $                          ONE, D, LDD, F, LDF, ONE,
-     $                          DWORK, P )
-         CALL DGEMM( 'NoTranspose', 'NoTranspose', N, N, P, ONE, G,
-     $               LDG, DWORK, P, ONE, A, LDA )
-         CALL DGEMM( 'NoTranspose', 'NoTranspose', N, N, M, ONE, B,
-     $               LDB, F, LDF, ONE, A, LDA )
-C
-         DWORK(1) = P*N
-         RETURN
-      END IF
-C
-      IF( BAL ) THEN
-         JOB = 'B'
-      ELSE
-         JOB = 'N'
-      END IF
-C
-C     Reduce the coprime factors.
-C
-      IF( LEFT ) THEN
-C
-C        Form Ge(d) = [ N_left(d) M_left(d) ] as
-C
-C             ( A+G*C |  G  B+GD )
-C             (------------------)
-C             (   F   |  0   I   )
-C
-C        Real workspace:    need  (N+M)*(M+P).
-C        Integer workspace: need  0.
-C
-         CALL DGEMM( 'NoTranspose', 'NoTranspose', N, N, P, ONE, G,
-     $               LDG, C, LDC, ONE, A, LDA )
-         KBE  = 1
-         KDE  = KBE + N*(P+M)
-         LDBE = MAX( 1, N )
-         LDDE = M
-         CALL DLACPY( 'Full', N, P, G, LDG, DWORK(KBE), LDBE )
-         CALL DLACPY( 'Full', N, M, B, LDB, DWORK(KBE+N*P), LDBE )
-         IF( WITHD ) CALL DGEMM( 'NoTranspose', 'NoTranspose', N, M, P,
-     $                          ONE, G, LDG, D, LDD, ONE,
-     $                          DWORK(KBE+N*P), LDBE )
-         CALL DLASET( 'Full', M, P, ZERO, ZERO, DWORK(KDE), LDDE )
-         CALL DLASET( 'Full', M, M, ZERO, ONE, DWORK(KDE+M*P), LDDE )
-C
-C        Compute the reduced coprime factors,
-C             Ger(d) = [ N_leftr(d) M_leftr(d) ] ,
-C        by using either the B&T or SPA methods.
-C
-C        Real workspace:    need  (N+M)*(M+P) +
-C                                 MAX(1,N*(2*N+MAX(N,M+P)+5)+N*(N+1)/2).
-C        Integer workspace: need  0,         if JOBMR = 'B',
-C                                 N,         if JOBMR = 'F', and
-C                                 MAX(1,2*N) if JOBMR = 'S' or 'P'.
-C
-         KW = KDE + M*(P+M)
-         IF( BTA ) THEN
-            CALL AB09AD( DICO, JOB, EQUIL, ORDSEL, N, M+P, M, NCR, A,
-     $                   LDA, DWORK(KBE), LDBE, F, LDF, HSV, TOL1,
-     $                   IWORK, DWORK(KW), LDWORK-KW+1, IWARN, INFO )
-         ELSE
-            CALL AB09BD( DICO, JOB, EQUIL, ORDSEL, N, M+P, M, NCR, A,
-     $                   LDA, DWORK(KBE), LDBE, F, LDF, DWORK(KDE),
-     $                   LDDE, HSV, TOL1, TOL2, IWORK, DWORK(KW),
-     $                   LDWORK-KW+1, IWARN, INFO )
-         END IF
-         IF( INFO.NE.0 )
-     $      RETURN
-C
-         WRKOPT = INT( DWORK(KW) ) + KW - 1
-C
-C        Compute the reduced order controller,
-C                             -1
-C           Kr(d) = M_leftr(d)  *N_leftr(d).
-C
-C        Real workspace:    need  (N+M)*(M+P) + MAX(1,4*M).
-C        Integer workspace: need  M.
-C
-         CALL SB08GD( NCR, P, M, A, LDA, DWORK(KBE), LDBE, F, LDF,
-     $                DWORK(KDE), LDDE, DWORK(KBE+N*P), LDBE,
-     $                DWORK(KDE+M*P), LDDE, IWORK, DWORK(KW), INFO )
-C
-C        Copy the reduced system matrices Bc and Dc.
-C
-         CALL DLACPY( 'Full', NCR, P, DWORK(KBE), LDBE, G, LDG )
-         CALL DLACPY( 'Full', M, P, DWORK(KDE), LDDE, DC, LDDC )
-C
-      ELSE
-C
-C        Form Ge(d) = [ N_right(d) ]
-C                     [ M_right(d) ] as
-C
-C             ( A+B*F | G )
-C             (-----------)
-C             (   F   | 0 )
-C             ( C+D*F | I )
-C
-C        Real workspace:    need  (N+P)*(M+P).
-C        Integer workspace: need  0.
-C
-         CALL DGEMM( 'NoTranspose', 'NoTranspose', N, N, M, ONE, B,
-     $               LDB, F, LDF, ONE, A, LDA )
-         KCE  = 1
-         KDE  = KCE + N*(P+M)
-         LDCE = M+P
-         LDDE = LDCE
-         CALL DLACPY( 'Full', M, N, F, LDF, DWORK(KCE), LDCE )
-         CALL DLACPY( 'Full', P, N, C, LDC, DWORK(KCE+M), LDCE )
-         IF( WITHD ) CALL DGEMM( 'NoTranspose', 'NoTranspose', P, N, M,
-     $                          ONE, D, LDD, F, LDF, ONE,
-     $                          DWORK(KCE+M), LDCE )
-         CALL DLASET( 'Full', M, P, ZERO, ZERO, DWORK(KDE), LDDE )
-         CALL DLASET( 'Full', P, P, ZERO, ONE, DWORK(KDE+M), LDDE )
-C
-C        Compute the reduced coprime factors,
-C             Ger(d) = [ N_rightr(d) ]
-C                      [ M_rightr(d) ],
-C        by using either the B&T or SPA methods.
-C
-C        Real workspace:    need  (N+P)*(M+P) +
-C                                 MAX(1,N*(2*N+MAX(N,M+P)+5)+N*(N+1)/2).
-C        Integer workspace: need  0,         if JOBMR = 'B',
-C                                 N,         if JOBMR = 'F', and
-C                                 MAX(1,2*N) if JOBMR = 'S' or 'P'.
-C
-         KW = KDE + P*(P+M)
-         IF( BTA ) THEN
-            CALL AB09AD( DICO, JOB, EQUIL, ORDSEL, N, P, M+P, NCR, A,
-     $                   LDA, G, LDG, DWORK(KCE), LDCE, HSV, TOL1,
-     $                   IWORK, DWORK(KW), LDWORK-KW+1, IWARN, INFO )
-         ELSE
-            CALL AB09BD( DICO, JOB, EQUIL, ORDSEL, N, P, M+P, NCR, A,
-     $                   LDA, G, LDG, DWORK(KCE), LDCE, DWORK(KDE),
-     $                   LDDE, HSV, TOL1, TOL2, IWORK, DWORK(KW),
-     $                   LDWORK-KW+1, IWARN, INFO )
-         END IF
-         IF( INFO.NE.0 ) THEN
-            IF( INFO.NE.3 ) INFO = INFO + 3
-            RETURN
-         END IF
-C
-         WRKOPT = INT( DWORK(KW) ) + KW - 1
-C
-C        Compute the reduced order controller,
-C                                        -1
-C           Kr(d) = N_rightr(d)*M_rightr(d) .
-C
-C        Real workspace:    need  (N+P)*(M+P) + MAX(1,4*P).
-C        Integer workspace: need  P.
-C
-         CALL SB08HD( NCR, P, M, A, LDA, G, LDG, DWORK(KCE), LDCE,
-     $                DWORK(KDE), LDDE, DWORK(KCE+M), LDCE,
-     $                DWORK(KDE+M), LDDE, IWORK, DWORK(KW), INFO )
-C
-C        Copy the reduced system matrices Cc and Dc.
-C
-         CALL DLACPY( 'Full', M, NCR, DWORK(KCE), LDCE, F, LDF )
-         CALL DLACPY( 'Full', M, P, DWORK(KDE), LDDE, DC, LDDC )
-C
-      END IF
-C
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of SB16BD ***
-      END
--- a/extra/control-devel/src/SB16CD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,526 +0,0 @@
-      SUBROUTINE SB16CD( DICO, JOBD, JOBMR, JOBCF, ORDSEL, N, M, P, NCR,
-     $                   A, LDA, B, LDB, C, LDC, D, LDD, F, LDF, G, LDG,
-     $                   HSV, TOL, IWORK, DWORK, LDWORK, IWARN, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute, for a given open-loop model (A,B,C,D), and for
-C     given state feedback gain F and full observer gain G,
-C     such that A+B*F and A+G*C are stable, a reduced order
-C     controller model (Ac,Bc,Cc) using a coprime factorization
-C     based controller reduction approach. For reduction of
-C     coprime factors, a stability enforcing frequency-weighted
-C     model reduction is performed using either the square-root or
-C     the balancing-free square-root versions of the Balance & Truncate
-C     (B&T) model reduction method.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the open-loop system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     JOBD    CHARACTER*1
-C             Specifies whether or not a non-zero matrix D appears
-C             in the given state space model, as follows:
-C             = 'D':  D is present;
-C             = 'Z':  D is assumed a zero matrix.
-C
-C     JOBMR   CHARACTER*1
-C             Specifies the model reduction approach to be used
-C             as follows:
-C             = 'B':  use the square-root B&T method;
-C             = 'F':  use the balancing-free square-root B&T method.
-C
-C     JOBCF   CHARACTER*1
-C             Specifies whether left or right coprime factorization
-C             of the controller is to be used as follows:
-C             = 'L':  use left coprime factorization;
-C             = 'R':  use right coprime factorization.
-C
-C     ORDSEL  CHARACTER*1
-C             Specifies the order selection method as follows:
-C             = 'F':  the resulting controller order NCR is fixed;
-C             = 'A':  the resulting controller order NCR is
-C                     automatically determined on basis of the given
-C                     tolerance TOL.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation, i.e.
-C             the order of the matrix A.  N >= 0.
-C             N also represents the order of the original state-feedback
-C             controller.
-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     NCR     (input/output) INTEGER
-C             On entry with ORDSEL = 'F', NCR is the desired order of
-C             the resulting reduced order controller.  0 <= NCR <= N.
-C             On exit, if INFO = 0, NCR is the order of the resulting
-C             reduced order controller. NCR is set as follows:
-C             if ORDSEL = 'F', NCR is equal to MIN(NCR,NCRMIN), where
-C             NCR is the desired order on entry, and NCRMIN is the
-C             number of Hankel-singular values greater than N*EPS*S1,
-C             where EPS is the machine precision (see LAPACK Library
-C             Routine DLAMCH) and S1 is the largest Hankel singular
-C             value (computed in HSV(1)); NCR can be further reduced
-C             to ensure HSV(NCR) > HSV(NCR+1);
-C             if ORDSEL = 'A', NCR is equal to the number of Hankel
-C             singular values greater than MAX(TOL,N*EPS*S1).
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the original state dynamics matrix A.
-C             On exit, if INFO = 0, the leading NCR-by-NCR part of this
-C             array contains the state dynamics matrix Ac of the reduced
-C             controller.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the open-loop system input/state matrix B.
-C             On exit, this array is overwritten with a NCR-by-M
-C             B&T approximation of the matrix B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the open-loop system state/output matrix C.
-C             On exit, this array is overwritten with a P-by-NCR
-C             B&T approximation of the matrix C.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     D       (input) DOUBLE PRECISION array, dimension (LDD,M)
-C             On entry, if JOBD = 'D', the leading P-by-M part of this
-C             array must contain the system direct input/output
-C             transmission matrix D.
-C             The array D is not referenced if JOBD = 'Z'.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.
-C             LDD >= MAX(1,P), if JOBD = 'D';
-C             LDD >= 1,        if JOBD = 'Z'.
-C
-C     F       (input/output) DOUBLE PRECISION array, dimension (LDF,N)
-C             On entry, the leading M-by-N part of this array must
-C             contain a stabilizing state feedback matrix.
-C             On exit, if INFO = 0, the leading M-by-NCR part of this
-C             array contains the output/state matrix Cc of the reduced
-C             controller.
-C
-C     LDF     INTEGER
-C             The leading dimension of array F.  LDF >= MAX(1,M).
-C
-C     G       (input/output) DOUBLE PRECISION array, dimension (LDG,P)
-C             On entry, the leading N-by-P part of this array must
-C             contain a stabilizing observer gain matrix.
-C             On exit, if INFO = 0, the leading NCR-by-P part of this
-C             array contains the input/state matrix Bc of the reduced
-C             controller.
-C
-C     LDG     INTEGER
-C             The leading dimension of array G.  LDG >= MAX(1,N).
-C
-C     HSV     (output) DOUBLE PRECISION array, dimension (N)
-C             If INFO = 0, HSV contains the N frequency-weighted
-C             Hankel singular values ordered decreasingly (see METHOD).
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             If ORDSEL = 'A', TOL contains the tolerance for
-C             determining the order of reduced controller.
-C             The recommended value is TOL = c*S1, where c is a constant
-C             in the interval [0.00001,0.001], and S1 is the largest
-C             Hankel singular value (computed in HSV(1)).
-C             The value TOL = N*EPS*S1 is used by default if
-C             TOL <= 0 on entry, where EPS is the machine precision
-C             (see LAPACK Library Routine DLAMCH).
-C             If ORDSEL = 'F', the value of TOL is ignored.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension LIWORK, where
-C             LIWORK = 0,   if JOBMR = 'B';
-C             LIWORK = N,   if JOBMR = 'F'.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= 2*N*N + MAX( 1, 2*N*N + 5*N, N*MAX(M,P),
-C                                    N*(N + MAX(N,MP) + MIN(N,MP) + 6)),
-C             where     MP = M, if JOBCF = 'L';
-C                       MP = P, if JOBCF = 'R'.
-C             For optimum performance LDWORK should be larger.
-C
-C     Warning Indicator
-C
-C     IWARN   INTEGER
-C             = 0:  no warning;
-C             = 1:  with ORDSEL = 'F', the selected order NCR is
-C                   greater than the order of a minimal realization
-C                   of the controller;
-C             = 2:  with ORDSEL = 'F', the selected order NCR
-C                   corresponds to repeated singular values, which are
-C                   neither all included nor all excluded from the
-C                   reduced controller. In this case, the resulting NCR
-C                   is set automatically to the largest value such that
-C                   HSV(NCR) > HSV(NCR+1).
-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:  eigenvalue computation failure;
-C             = 2:  the matrix A+G*C is not stable;
-C             = 3:  the matrix A+B*F is not stable;
-C             = 4:  the Lyapunov equation for computing the
-C                   observability Grammian is (nearly) singular;
-C             = 5:  the Lyapunov equation for computing the
-C                   controllability Grammian is (nearly) singular;
-C             = 6:  the computation of Hankel singular values failed.
-C
-C     METHOD
-C
-C     Let be the linear system
-C
-C          d[x(t)] = Ax(t) + Bu(t)
-C          y(t)    = Cx(t) + Du(t),                             (1)
-C
-C     where d[x(t)] is dx(t)/dt for a continuous-time system and x(t+1)
-C     for a discrete-time system, and let Go(d) be the open-loop
-C     transfer-function matrix
-C                          -1
-C          Go(d) = C*(d*I-A) *B + D .
-C
-C     Let F and G be the state feedback and observer gain matrices,
-C     respectively, chosen such that A+BF and A+GC are stable matrices.
-C     The controller has a transfer-function matrix K(d) given by
-C                                       -1
-C          K(d) = F*(d*I-A-B*F-G*C-G*D*F) *G .
-C
-C     The closed-loop transfer function matrix is given by
-C                                    -1
-C          Gcl(d) = Go(d)(I+K(d)Go(d)) .
-C
-C     K(d) can be expressed as a left coprime factorization (LCF)
-C                         -1
-C          K(d) = M_left(d) *N_left(d),
-C
-C     or as a right coprime factorization (RCF)
-C                                     -1
-C          K(d) = N_right(d)*M_right(d) ,
-C
-C     where M_left(d), N_left(d), N_right(d), and M_right(d) are
-C     stable transfer-function matrices.
-C
-C     The subroutine SB16CD determines the matrices of a reduced
-C     controller
-C
-C          d[z(t)] = Ac*z(t) + Bc*y(t)
-C          u(t)    = Cc*z(t),                                   (2)
-C
-C     with the transfer-function matrix Kr, using the following
-C     stability enforcing approach proposed in [1]:
-C
-C     (1) If JOBCF = 'L', the frequency-weighted approximation problem
-C         is solved
-C
-C         min||[M_left(d)-M_leftr(d)  N_left(d)-N_leftr(d)][-Y(d)]|| ,
-C                                                          [ X(d)]
-C         where
-C                              -1
-C               G(d) = Y(d)*X(d)
-C
-C         is a RCF of the open-loop system transfer-function matrix.
-C         The B&T model reduction technique is used in conjunction
-C         with the method proposed in [1].
-C
-C     (2) If JOBCF = 'R', the frequency-weighted approximation problem
-C         is solved
-C
-C         min || [ -U(d) V(d) ] [ N_right(d)-N_rightr(d) ] || ,
-C                               [ M_right(d)-M_rightr(d) ]
-C         where
-C                         -1
-C               G(d) = V(d) *U(d)
-C
-C         is a LCF of the open-loop system transfer-function matrix.
-C         The B&T model reduction technique is used in conjunction
-C         with the method proposed in [1].
-C
-C     If ORDSEL = 'A', the order of the controller is determined by
-C     computing the number of Hankel singular values greater than
-C     the given tolerance TOL. The Hankel singular values are
-C     the square roots of the eigenvalues of the product of
-C     two frequency-weighted Grammians P and Q, defined as follows.
-C
-C     If JOBCF = 'L', then P is the controllability Grammian of a system
-C     of the form (A+BF,B,*,*), and Q is the observability Grammian of a
-C     system of the form (A+GC,*,F,*). This choice corresponds to an
-C     input frequency-weighted order reduction of left coprime
-C     factors [1].
-C
-C     If JOBCF = 'R', then P is the controllability Grammian of a system
-C     of the form (A+BF,G,*,*), and Q is the observability Grammian of a
-C     system of the form (A+GC,*,C,*). This choice corresponds to an
-C     output frequency-weighted order reduction of right coprime
-C     factors [1].
-C
-C     For the computation of truncation matrices, the B&T approach
-C     is used in conjunction with accuracy enhancing techniques.
-C     If JOBMR = 'B', the square-root B&T method of [2,4] is used.
-C     If JOBMR = 'F', the balancing-free square-root version of the
-C     B&T method [3,4] is used.
-C
-C     REFERENCES
-C
-C     [1] Liu, Y., Anderson, B.D.O. and Ly, O.L.
-C         Coprime factorization controller reduction with Bezout
-C         identity induced frequency weighting.
-C         Automatica, vol. 26, pp. 233-249, 1990.
-C
-C     [2] Tombs, M.S. and Postlethwaite I.
-C         Truncated balanced realization of stable, non-minimal
-C         state-space systems.
-C         Int. J. Control, Vol. 46, pp. 1319-1330, 1987.
-C
-C     [3] Varga, A.
-C         Efficient minimal realization procedure based on balancing.
-C         Proc. of IMACS/IFAC Symp. MCTS, Lille, France, May 1991,
-C         A. El Moudui, P. Borne, S. G. Tzafestas (Eds.), Vol. 2,
-C         pp. 42-46, 1991.
-C
-C     [4] Varga, A.
-C         Coprime factors model reduction method based on square-root
-C         balancing-free techniques.
-C         System Analysis, Modelling and Simulation, Vol. 11,
-C         pp. 303-311, 1993.
-C
-C     NUMERICAL ASPECTS
-C
-C     The implemented methods rely on accuracy enhancing square-root or
-C     balancing-free square-root techniques.
-C                                         3
-C     The algorithms require less than 30N  floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, October 2000.
-C     D. Sima, University of Bucharest, October 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2000.
-C
-C     REVISIONS
-C
-C     A. Varga, Australian National University, Canberra, November 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Aug. 2001.
-C
-C     KEYWORDS
-C
-C     Controller reduction, coprime factorization, frequency weighting,
-C     multivariable system, state-space model.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ONE, ZERO
-      PARAMETER         ( ONE = 1.0D0, ZERO = 0.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         DICO, JOBCF, JOBD, JOBMR, ORDSEL
-      INTEGER           INFO, IWARN, LDA, LDB, LDC, LDD,
-     $                  LDF, LDG, LDWORK, M, N, NCR, P
-      DOUBLE PRECISION  TOL
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                  DWORK(*), F(LDF,*), G(LDG,*), HSV(*)
-C     .. Local Scalars ..
-      LOGICAL           BAL, DISCR, FIXORD, LEFT, WITHD
-      INTEGER           IERR, KT, KTI, KW, LW, MP, NMR, WRKOPT
-      DOUBLE PRECISION  SCALEC, SCALEO
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB09IX, DGEMM, DLACPY, SB16CY, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         INT, MAX, MIN
-C     .. Executable Statements ..
-C
-      INFO   = 0
-      IWARN  = 0
-      DISCR  = LSAME( DICO,   'D' )
-      WITHD  = LSAME( JOBD,   'D' )
-      BAL    = LSAME( JOBMR,  'B' )
-      LEFT   = LSAME( JOBCF,  'L' )
-      FIXORD = LSAME( ORDSEL, 'F' )
-      IF( LEFT ) THEN
-         MP = M
-      ELSE
-         MP = P
-      END IF
-      LW = 2*N*N + MAX( 1, 2*N*N + 5*N, N*MAX( M, P ),
-     $                  N*( N + MAX( N, MP ) + MIN( N, MP ) + 6 ) )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( WITHD  .OR. LSAME( JOBD,   'Z' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( BAL    .OR. LSAME( JOBMR,  'F' ) ) ) THEN
-         INFO = -3
-      ELSE IF( .NOT. ( LEFT   .OR. LSAME( JOBCF,  'R' ) ) ) THEN
-         INFO = -4
-      ELSE IF( .NOT. ( FIXORD .OR. LSAME( ORDSEL, 'A' ) ) ) THEN
-         INFO = -5
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -7
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -8
-      ELSE IF( FIXORD .AND. ( NCR.LT.0 .OR. NCR.GT.N ) ) THEN
-         INFO = -9
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -13
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -15
-      ELSE IF( LDD.LT.1 .OR. ( WITHD .AND. LDD.LT.P ) ) THEN
-         INFO = -17
-      ELSE IF( LDF.LT.MAX( 1, M ) ) THEN
-         INFO = -19
-      ELSE IF( LDG.LT.MAX( 1, N ) ) THEN
-         INFO = -21
-      ELSE IF( LDWORK.LT.LW ) THEN
-         INFO = -26
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB16CD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 .OR.
-     $    ( FIXORD .AND. NCR.EQ.0 ) ) THEN
-         NCR = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Allocate working storage.
-C
-      KT  = 1
-      KTI = KT  + N*N
-      KW  = KTI + N*N
-C
-C     Compute in DWORK(KTI) and DWORK(KT) the Cholesky factors Su and Ru
-C     of the frequency-weighted controllability and observability
-C     Grammians, respectively.
-C
-C     Workspace:   need 2*N*N + MAX(1, N*(N + MAX(N,M) + MIN(N,M) + 6)),
-C                                                        if JOBCF = 'L';
-C                       2*N*N + MAX(1, N*(N + MAX(N,P) + MIN(N,P) + 6)),
-C                                                        if JOBCF = 'R'.
-C                  prefer larger.
-C
-      CALL SB16CY( DICO, JOBCF, N, M, P, A, LDA, B, LDB, C, LDC,
-     $             F, LDF, G, LDG, SCALEC, SCALEO, DWORK(KTI), N,
-     $             DWORK(KT), N, DWORK(KW), LDWORK-KW+1, INFO )
-C
-      IF( INFO.NE.0 )
-     $   RETURN
-      WRKOPT = INT( DWORK(KW) ) + KW - 1
-C
-C     Compute a B&T approximation (Ar,Br,Cr) of (A,B,C) and
-C     the corresponding truncation matrices TI and T.
-C
-C     Real workspace:  need   2*N*N + MAX( 1, 2*N*N+5*N, N*MAX(M,P) );
-C                      prefer larger.
-C     Integer workspace:  0,  if JOBMR = 'B';
-C                         N,  if JOBMR = 'F'.
-C
-      CALL AB09IX( DICO, JOBMR, 'NotSchur', ORDSEL, N, M, P, NCR,
-     $             SCALEC, SCALEO, A, LDA, B, LDB, C, LDC, D, LDD,
-     $             DWORK(KTI), N, DWORK(KT), N, NMR, HSV, TOL, TOL,
-     $             IWORK, DWORK(KW), LDWORK-KW+1, IWARN, IERR )
-      IF( IERR.NE.0 ) THEN
-         INFO = 6
-         RETURN
-      END IF
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-C
-C     Compute reduced gains Bc = Gr = TI*G and Cc = Fr = F*T.
-C     Workspace:  need   N*(2*N+MAX(M,P)).
-C
-      CALL DLACPY( 'Full', N, P, G, LDG, DWORK(KW), N )
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NCR, P, N, ONE,
-     $            DWORK(KTI), N, DWORK(KW), N, ZERO, G, LDG )
-C
-      CALL DLACPY( 'Full', M, N, F, LDF, DWORK(KW), M )
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', M, NCR, N, ONE,
-     $            DWORK(KW), M, DWORK(KT), N, ZERO, F, LDF )
-C
-C     Form the reduced controller state matrix,
-C     Ac = Ar + Br*Fr + Gr*Cr + Gr*D*Fr = Ar + Br*Fr + Gr*(Cr+D*Fr) .
-C
-C     Workspace:    need  P*N.
-C
-      CALL DLACPY( 'Full', P, NCR, C, LDC, DWORK, P )
-      IF( WITHD) CALL DGEMM( 'NoTranspose', 'NoTranspose', P, NCR, M,
-     $                       ONE, D, LDD, F, LDF, ONE, DWORK, P )
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NCR, NCR, P, ONE, G,
-     $            LDG, DWORK, P, ONE, A, LDA )
-      CALL DGEMM( 'NoTranspose', 'NoTranspose', NCR, NCR, M, ONE, B,
-     $            LDB, F, LDF, ONE, A, LDA )
-C
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of SB16CD ***
-      END
--- a/extra/control-devel/src/SB16CY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,409 +0,0 @@
-      SUBROUTINE SB16CY( DICO, JOBCF, N, M, P, A, LDA, B, LDB, C, LDC,
-     $                   F, LDF, G, LDG, SCALEC, SCALEO, S, LDS, R, LDR,
-     $                   DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute, for a given open-loop model (A,B,C,0), and for
-C     given state feedback gain F and full observer gain G,
-C     such that A+B*F and A+G*C are stable, the Cholesky factors
-C     Su and Ru of a controllability Grammian P = Su*Su' and of
-C     an observability Grammian Q = Ru'*Ru corresponding to a
-C     frequency-weighted model reduction of the left or right coprime
-C     factors of the state-feedback controller.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the open-loop system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     JOBCF   CHARACTER*1
-C             Specifies whether a left or right coprime factorization
-C             of the state-feedback controller is to be used as follows:
-C             = 'L':  use a left coprime factorization;
-C             = 'R':  use a right coprime factorization.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the open-loop state-space representation,
-C             i.e., the order of the matrix A.  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     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 open-loop 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,M)
-C             The leading N-by-M part of this array must contain the
-C             input/state matrix B of the open-loop system.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input) DOUBLE PRECISION array, dimension (LDC,N)
-C             The leading P-by-N part of this array must contain the
-C             state/output matrix C of the open-loop system.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     F       (input) DOUBLE PRECISION array, dimension (LDF,N)
-C             The leading M-by-N part of this array must contain a
-C             stabilizing state feedback matrix.
-C
-C     LDF     INTEGER
-C             The leading dimension of array F.  LDF >= MAX(1,M).
-C
-C     G       (input) DOUBLE PRECISION array, dimension (LDG,P)
-C             The leading N-by-P part of this array must contain a
-C             stabilizing observer gain matrix.
-C
-C     LDG     INTEGER
-C             The leading dimension of array G.  LDG >= MAX(1,N).
-C
-C     SCALEC  (output) DOUBLE PRECISION
-C             Scaling factor for the controllability Grammian.
-C             See METHOD.
-C
-C     SCALEO  (output) DOUBLE PRECISION
-C             Scaling factor for the observability Grammian.
-C             See METHOD.
-C
-C     S       (output) DOUBLE PRECISION array, dimension (LDS,N)
-C             The leading N-by-N upper triangular part of this array
-C             contains the Cholesky factor Su of frequency-weighted
-C             cotrollability Grammian P = Su*Su'. See METHOD.
-C
-C     LDS     INTEGER
-C             The leading dimension of the array S.  LDS >= MAX(1,N).
-C
-C     R       (output) DOUBLE PRECISION array, dimension (LDR,N)
-C             The leading N-by-N upper triangular part of this array
-C             contains the Cholesky factor Ru of the frequency-weighted
-C             observability Grammian Q = Ru'*Ru. See METHOD.
-C
-C     LDR     INTEGER
-C             The leading dimension of the array R.  LDR >= MAX(1,N).
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1, N*(N + MAX(N,M) + MIN(N,M) + 6)),
-C                                                       if JOBCF = 'L';
-C             LDWORK >= MAX(1, N*(N + MAX(N,P) + MIN(N,P) + 6)),
-C                                                       if JOBCF = 'R'.
-C             For optimum performance LDWORK should be larger.
-C             An upper bound for both cases is
-C             LDWORK >= MAX(1, N*(N + MAX(N,M,P) + 7)).
-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:  eigenvalue computation failure;
-C             = 2:  the matrix A+G*C is not stable;
-C             = 3:  the matrix A+B*F is not stable;
-C             = 4:  the Lyapunov equation for computing the
-C                   observability Grammian is (nearly) singular;
-C             = 5:  the Lyapunov equation for computing the
-C                   controllability Grammian is (nearly) singular.
-C
-C     METHOD
-C
-C     In accordance with the type of the coprime factorization
-C     of the controller (left or right), the Cholesky factors Su and Ru
-C     of the frequency-weighted controllability Grammian P = Su*Su' and
-C     of the frequency-weighted observability Grammian Q = Ru'*Ru are
-C     computed by solving appropriate Lyapunov or Stein equations [1].
-C
-C     If JOBCF = 'L' and DICO = 'C', P and Q are computed as the
-C     solutions of the following Lyapunov equations:
-C
-C            (A+B*F)*P + P*(A+B*F)' +  scalec^2*B*B' = 0,  (1)
-C
-C            (A+G*C)'*Q + Q*(A+G*C) +  scaleo^2*F'*F = 0.  (2)
-C
-C     If JOBCF = 'L' and DICO = 'D', P and Q are computed as the
-C     solutions of the following Stein equations:
-C
-C            (A+B*F)*P*(A+B*F)' - P +  scalec^2*B*B' = 0,  (3)
-C
-C            (A+G*C)'*Q*(A+G*C) - Q +  scaleo^2*F'*F = 0.  (4)
-C
-C     If JOBCF = 'R' and DICO = 'C', P and Q are computed as the
-C     solutions of the following Lyapunov equations:
-C
-C            (A+B*F)*P + P*(A+B*F)' +  scalec^2*G*G' = 0,  (5)
-C
-C            (A+G*C)'*Q + Q*(A+G*C) +  scaleo^2*C'*C = 0.  (6)
-C
-C     If JOBCF = 'R' and DICO = 'D', P and Q are computed as the
-C     solutions of the following Stein equations:
-C
-C            (A+B*F)*P*(A+B*F)' - P +  scalec^2*G*G' = 0,  (7)
-C
-C            (A+G*C)'*Q*(A+G*C) - Q +  scaleo^2*C'*C = 0.  (8)
-C
-C     REFERENCES
-C
-C     [1] Liu, Y., Anderson, B.D.O. and Ly, O.L.
-C         Coprime factorization controller reduction with Bezout
-C         identity induced frequency weighting.
-C         Automatica, vol. 26, pp. 233-249, 1990.
-C
-C     CONTRIBUTORS
-C
-C     A. Varga, German Aerospace Center, Oberpfaffenhofen, October 2000.
-C     D. Sima, University of Bucharest, October 2000.
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2000.
-C
-C     REVISIONS
-C
-C     A. Varga, Australian National University, Canberra, November 2000.
-C
-C     KEYWORDS
-C
-C     Controller reduction, frequency weighting, multivariable system,
-C     state-space model, state-space representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION ZERO, ONE
-      PARAMETER        ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER        DICO, JOBCF
-      INTEGER          INFO, LDA, LDB, LDC, LDF, LDG, LDR, LDS, LDWORK,
-     $                 M, N, P
-      DOUBLE PRECISION SCALEC, SCALEO
-C     .. Array Arguments ..
-      DOUBLE PRECISION A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*),
-     $                 F(LDF,*), G(LDG,*), R(LDR,*), S(LDS,*)
-C     .. Local Scalars ..
-      LOGICAL          DISCR, LEFTW
-      INTEGER          IERR, KAW, KU, KW, KWI, KWR, LDU, LW, ME, MP,
-     $                 WRKOPT
-C     .. External Functions ..
-      LOGICAL          LSAME
-      EXTERNAL         LSAME
-C     .. External Subroutines ..
-      EXTERNAL         DGEMM, DLACPY, SB03OD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC        INT, MAX, MIN
-C     .. Executable Statements ..
-C
-      DISCR = LSAME( DICO,  'D' )
-      LEFTW = LSAME( JOBCF, 'L' )
-C
-      INFO = 0
-      IF( LEFTW ) THEN
-         MP = M
-      ELSE
-         MP = P
-      END IF
-      LW = N*( N + MAX( N, MP ) + MIN( N, MP ) + 6 )
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.( LEFTW .OR. LSAME( JOBCF, 'R' ) ) ) THEN
-         INFO = -2
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -11
-      ELSE IF( LDF.LT.MAX( 1, M ) ) THEN
-         INFO = -13
-      ELSE IF( LDG.LT.MAX( 1, N ) ) THEN
-         INFO = -15
-      ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
-         INFO = -19
-      ELSE IF( LDR.LT.MAX( 1, N ) ) THEN
-         INFO = -21
-      ELSE IF( LDWORK.LT.MAX( 1, LW ) ) THEN
-         INFO = -23
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'SB16CY', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( MIN( N, M, P ).EQ.0 ) THEN
-         SCALEC   = ONE
-         SCALEO   = ONE
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Allocate storage for work arrays.
-C
-      KAW = 1
-      KU  = KAW + N*N
-      KWR = KU  + N*MAX( N, MP )
-      KWI = KWR + N
-      KW  = KWI + N
-C
-C     Form A+G*C.
-C
-      CALL DLACPY( 'Full', N, N, A, LDA, DWORK(KAW), N )
-      CALL DGEMM( 'No-transpose', 'No-transpose', N, N, P, ONE,
-     $            G, LDG, C, LDC, ONE, DWORK(KAW), N )
-C
-C     Form the factor H of the free term.
-C
-      IF( LEFTW ) THEN
-C
-C        H = F.
-C
-         LDU = MAX( N, M )
-         ME  = M
-         CALL DLACPY( 'Full', M, N, F, LDF, DWORK(KU), LDU )
-      ELSE
-C
-C        H = C.
-C
-         LDU = MAX( N, P )
-         ME  = P
-         CALL DLACPY( 'Full', P, N, C, LDC, DWORK(KU), LDU )
-      END IF
-C
-C     Solve for the Cholesky factor Ru of Q, Q = Ru'*Ru,
-C     the continuous-time Lyapunov equation (if DICO = 'C')
-C
-C        (A+G*C)'*Q + Q*(A+G*C) +  scaleo^2*H'*H = 0,
-C
-C     or the discrete-time Lyapunov equation (if DICO = 'D')
-C
-C        (A+G*C)'*Q*(A+G*C) - Q +  scaleo^2*H'*H = 0.
-C
-C     Workspace:  need   N*(N + MAX(N,M) + MIN(N,M) + 6) if JOBCF = 'L';
-C                        N*(N + MAX(N,P) + MIN(N,P) + 6) if JOBCF = 'R'.
-C                 prefer larger.
-C
-      CALL SB03OD( DICO, 'NoFact', 'NoTransp', N, ME, DWORK(KAW), N,
-     $             R, LDR, DWORK(KU), LDU, SCALEO, DWORK(KWR),
-     $             DWORK(KWI), DWORK(KW), LDWORK-KW+1, IERR )
-      IF( IERR.NE.0 ) THEN
-         IF( IERR.EQ.2 ) THEN
-            INFO = 2
-         ELSE IF( IERR.EQ.1 ) THEN
-            INFO = 4
-         ELSE IF( IERR.EQ.6 ) THEN
-            INFO = 1
-         END IF
-         RETURN
-      END IF
-C
-      WRKOPT = INT( DWORK(KW) ) + KW - 1
-      CALL DLACPY( 'Upper', N, N, DWORK(KU), LDU, R, LDR )
-C
-C     Form A+B*F.
-C
-      CALL DLACPY( 'Full', N, N, A, LDA, DWORK(KAW), N )
-      CALL DGEMM( 'No-transpose', 'No-transpose', N, N, M, ONE,
-     $            B, LDB, F, LDF, ONE, DWORK(KAW), N )
-C
-C     Form the factor K of the free term.
-C
-      LDU = N
-      IF( LEFTW ) THEN
-C
-C        K = B.
-C
-         ME = M
-         CALL DLACPY( 'Full', N, M, B, LDB, DWORK(KU), LDU )
-      ELSE
-C
-C        K = G.
-C
-         ME = P
-         CALL DLACPY( 'Full', N, P, G, LDG, DWORK(KU), LDU )
-      END IF
-C
-C     Solve for the Cholesky factor Su of P, P = Su*Su',
-C     the continuous-time Lyapunov equation (if DICO = 'C')
-C
-C         (A+B*F)*P + P*(A+B*F)' +  scalec^2*K*K' = 0,
-C
-C     or the discrete-time Lyapunov equation (if DICO = 'D')
-C
-C         (A+B*F)*P*(A+B*F)' - P +  scalec^2*K*K' = 0.
-C
-C     Workspace:  need   N*(N + MAX(N,M) + MIN(N,M) + 6) if JOBCF = 'L';
-C                        N*(N + MAX(N,P) + MIN(N,P) + 6) if JOBCF = 'R'.
-C                        prefer larger.
-C
-      CALL SB03OD( DICO, 'NoFact', 'Transp', N, ME, DWORK(KAW), N,
-     $             S, LDS, DWORK(KU), LDU, SCALEC, DWORK(KWR),
-     $             DWORK(KWI), DWORK(KW), LDWORK-KW+1, IERR )
-      IF( IERR.NE.0 ) THEN
-         IF( IERR.EQ.2 ) THEN
-            INFO = 3
-         ELSE IF( IERR.EQ.1 ) THEN
-            INFO = 5
-         ELSE IF( IERR.EQ.6 ) THEN
-            INFO = 1
-         END IF
-         RETURN
-      END IF
-      WRKOPT = MAX( WRKOPT, INT( DWORK(KW) ) + KW - 1 )
-      CALL DLACPY( 'Upper', N, N, DWORK(KU), LDU, S, LDS )
-C
-C     Save the optimal workspace.
-C
-      DWORK(1) = WRKOPT
-C
-      RETURN
-C *** Last line of SB16CY ***
-      END
--- a/extra/control-devel/src/TB01ID.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,402 +0,0 @@
-      SUBROUTINE TB01ID( JOB, N, M, P, MAXRED, A, LDA, B, LDB, C, LDC,
-     $                   SCALE, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To reduce the 1-norm of a system matrix
-C
-C             S =  ( A  B )
-C                  ( C  0 )
-C
-C     corresponding to the triple (A,B,C), by balancing. This involves
-C     a diagonal similarity transformation inv(D)*A*D applied
-C     iteratively to A to make the rows and columns of
-C                           -1
-C                  diag(D,I)  * S * diag(D,I)
-C
-C     as close in norm as possible.
-C
-C     The balancing can be performed optionally on the following
-C     particular system matrices
-C
-C              S = A,    S = ( A  B )    or    S = ( A )
-C                                                  ( C )
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Indicates which matrices are involved in balancing, as
-C             follows:
-C             = 'A':  All matrices are involved in balancing;
-C             = 'B':  B and A matrices are involved in balancing;
-C             = 'C':  C and A matrices are involved in balancing;
-C             = 'N':  B and C matrices are not involved in balancing.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix A, the number of rows of matrix B
-C             and the number of columns of matrix C.
-C             N represents the dimension of the state vector.  N >= 0.
-C
-C     M       (input) INTEGER.
-C             The number of columns of matrix B.
-C             M represents the dimension of input vector.  M >= 0.
-C
-C     P       (input) INTEGER.
-C             The number of rows of matrix C.
-C             P represents the dimension of output vector.  P >= 0.
-C
-C     MAXRED  (input/output) DOUBLE PRECISION
-C             On entry, the maximum allowed reduction in the 1-norm of
-C             S (in an iteration) if zero rows or columns are
-C             encountered.
-C             If MAXRED > 0.0, MAXRED must be larger than one (to enable
-C             the norm reduction).
-C             If MAXRED <= 0.0, then the value 10.0 for MAXRED is
-C             used.
-C             On exit, if the 1-norm of the given matrix S is non-zero,
-C             the ratio between the 1-norm of the given matrix and the
-C             1-norm of the balanced matrix.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the system state matrix A.
-C             On exit, the leading N-by-N part of this array contains
-C             the balanced matrix inv(D)*A*D.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= max(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, if M > 0, the leading N-by-M part of this array
-C             must contain the system input matrix B.
-C             On exit, if M > 0, the leading N-by-M part of this array
-C             contains the balanced matrix inv(D)*B.
-C             The array B is not referenced if M = 0.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.
-C             LDB >= MAX(1,N) if M > 0.
-C             LDB >= 1        if M = 0.
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, if P > 0, the leading P-by-N part of this array
-C             must contain the system output matrix C.
-C             On exit, if P > 0, the leading P-by-N part of this array
-C             contains the balanced matrix C*D.
-C             The array C is not referenced if P = 0.
-C
-C     LDC     INTEGER
-C             The leading dimension of the array C.  LDC >= MAX(1,P).
-C
-C     SCALE   (output) DOUBLE PRECISION array, dimension (N)
-C             The scaling factors applied to S.  If D(j) is the scaling
-C             factor applied to row and column j, then SCALE(j) = D(j),
-C             for j = 1,...,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
-C     METHOD
-C
-C     Balancing consists of applying a diagonal similarity
-C     transformation
-C                           -1
-C                  diag(D,I)  * S * diag(D,I)
-C
-C     to make the 1-norms of each row of the first N rows of S and its
-C     corresponding column nearly equal.
-C
-C     Information about the diagonal matrix D is returned in the vector
-C     SCALE.
-C
-C     REFERENCES
-C
-C     [1] Anderson, E., Bai, Z., Bischof, C., Demmel, J., Dongarra, J.,
-C         Du Croz, J., Greenbaum, A., Hammarling, S., McKenney, A.,
-C         Ostrouchov, S., and Sorensen, D.
-C         LAPACK Users' Guide: Second Edition.
-C         SIAM, Philadelphia, 1995.
-C
-C     NUMERICAL ASPECTS
-C
-C     None.
-C
-C     CONTRIBUTOR
-C
-C     Release 3.0: V. Sima, Katholieke Univ. Leuven, Belgium, Jan. 1998.
-C     This subroutine is based on LAPACK routine DGEBAL, and routine
-C     BALABC (A. Varga, German Aerospace Research Establishment, DLR).
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Balancing, eigenvalue, matrix algebra, matrix operations,
-C     similarity transformation.
-C
-C  *********************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION   ZERO, ONE
-      PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
-      DOUBLE PRECISION   SCLFAC
-      PARAMETER          ( SCLFAC = 1.0D+1 )
-      DOUBLE PRECISION   FACTOR, MAXR
-      PARAMETER          ( FACTOR = 0.95D+0, MAXR = 10.0D+0 )
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          JOB
-      INTEGER            INFO, LDA, LDB, LDC, M, N, P
-      DOUBLE PRECISION   MAXRED
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), C( LDC, * ),
-     $                   SCALE( * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            NOCONV, WITHB, WITHC
-      INTEGER            I, ICA, IRA, J
-      DOUBLE PRECISION   CA, CO, F, G, MAXNRM, RA, RO, S, SFMAX1,
-     $                   SFMAX2, SFMIN1, SFMIN2, SNORM, SRED
-C     ..
-C     .. External Functions ..
-      LOGICAL            LSAME
-      INTEGER            IDAMAX
-      DOUBLE PRECISION   DASUM, DLAMCH
-      EXTERNAL           DASUM, DLAMCH, IDAMAX, LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DSCAL, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          ABS, MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-C     Test the scalar input arguments.
-C
-      INFO  = 0
-      WITHB = LSAME( JOB, 'A' ) .OR. LSAME( JOB, 'B' )
-      WITHC = LSAME( JOB, 'A' ) .OR. LSAME( JOB, 'C' )
-C
-      IF( .NOT.WITHB .AND. .NOT.WITHC .AND. .NOT.LSAME( JOB, 'N' ) )
-     $   THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( MAXRED.GT.ZERO .AND. MAXRED.LT.ONE ) THEN
-         INFO = -5
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( ( M.GT.0 .AND. LDB.LT.MAX( 1, N ) ) .OR.
-     $         ( M.EQ.0 .AND. LDB.LT.1 ) ) THEN
-         INFO = -9
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -11
-      END IF
-      IF( INFO.NE.0 ) THEN
-         CALL XERBLA( 'TB01ID', -INFO )
-         RETURN
-      END IF
-C
-      IF( N.EQ.0 )
-     $   RETURN
-C
-C     Compute the 1-norm of the required part of matrix S and exit if
-C     it is zero.
-C
-      SNORM = ZERO
-C
-      DO 10 J = 1, N
-         SCALE( J ) = ONE
-         CO = DASUM( N, A( 1, J ), 1 )
-         IF( WITHC .AND. P.GT.0 )
-     $      CO = CO + DASUM( P, C( 1, J ), 1 )
-         SNORM = MAX( SNORM, CO )
-   10 CONTINUE
-C
-      IF( WITHB ) THEN
-C
-         DO 20 J = 1, M
-            SNORM = MAX( SNORM, DASUM( N, B( 1, J ), 1 ) )
-   20    CONTINUE
-C
-      END IF
-C
-      IF( SNORM.EQ.ZERO )
-     $   RETURN
-C
-C     Set some machine parameters and the maximum reduction in the
-C     1-norm of S if zero rows or columns are encountered.
-C
-      SFMIN1 = DLAMCH( 'S' ) / DLAMCH( 'P' )
-      SFMAX1 = ONE / SFMIN1
-      SFMIN2 = SFMIN1*SCLFAC
-      SFMAX2 = ONE / SFMIN2
-C
-      SRED = MAXRED
-      IF( SRED.LE.ZERO ) SRED = MAXR
-C
-      MAXNRM = MAX( SNORM/SRED, SFMIN1 )
-C
-C     Balance the matrix.
-C
-C     Iterative loop for norm reduction.
-C
-   30 CONTINUE
-      NOCONV = .FALSE.
-C
-      DO 90 I = 1, N
-         CO = ZERO
-         RO = ZERO
-C
-         DO 40 J = 1, N
-            IF( J.EQ.I )
-     $         GO TO 40
-            CO = CO + ABS( A( J, I ) )
-            RO = RO + ABS( A( I, J ) )
-   40    CONTINUE
-C
-         ICA = IDAMAX( N, A( 1, I ), 1 )
-         CA  = ABS( A( ICA, I ) )
-         IRA = IDAMAX( N, A( I, 1 ), LDA )
-         RA  = ABS( A( I, IRA ) )
-C
-         IF( WITHC .AND. P.GT.0 ) THEN
-            CO  = CO + DASUM( P, C( 1, I ), 1 )
-            ICA = IDAMAX( P, C( 1, I ), 1 )
-            CA  = MAX( CA, ABS( C( ICA, I ) ) )
-         END IF
-C
-         IF( WITHB .AND. M.GT.0 ) THEN
-            RO  = RO + DASUM( M, B( I, 1 ), LDB )
-            IRA = IDAMAX( M, B( I, 1 ), LDB )
-            RA  = MAX( RA, ABS( B( I, IRA ) ) )
-         END IF
-C
-C        Special case of zero CO and/or RO.
-C
-         IF( CO.EQ.ZERO .AND. RO.EQ.ZERO )
-     $      GO TO 90
-         IF( CO.EQ.ZERO ) THEN
-            IF( RO.LE.MAXNRM )
-     $         GO TO 90
-            CO = MAXNRM
-         END IF
-         IF( RO.EQ.ZERO ) THEN
-            IF( CO.LE.MAXNRM )
-     $         GO TO 90
-            RO = MAXNRM
-         END IF
-C
-C        Guard against zero CO or RO due to underflow.
-C
-         G = RO / SCLFAC
-         F = ONE
-         S = CO + RO
-   50    CONTINUE
-         IF( CO.GE.G .OR. MAX( F, CO, CA ).GE.SFMAX2 .OR.
-     $       MIN( RO, G, RA ).LE.SFMIN2 )GO TO 60
-         F  =  F*SCLFAC
-         CO = CO*SCLFAC
-         CA = CA*SCLFAC
-         G  =  G / SCLFAC
-         RO = RO / SCLFAC
-         RA = RA / SCLFAC
-         GO TO 50
-C
-   60    CONTINUE
-         G = CO / SCLFAC
-   70    CONTINUE
-         IF( G.LT.RO .OR. MAX( RO, RA ).GE.SFMAX2 .OR.
-     $       MIN( F, CO, G, CA ).LE.SFMIN2 )GO TO 80
-         F  =  F / SCLFAC
-         CO = CO / SCLFAC
-         CA = CA / SCLFAC
-         G  =  G / SCLFAC
-         RO = RO*SCLFAC
-         RA = RA*SCLFAC
-         GO TO 70
-C
-C        Now balance.
-C
-   80    CONTINUE
-         IF( ( CO+RO ).GE.FACTOR*S )
-     $      GO TO 90
-         IF( F.LT.ONE .AND. SCALE( I ).LT.ONE ) THEN
-            IF( F*SCALE( I ).LE.SFMIN1 )
-     $         GO TO 90
-         END IF
-         IF( F.GT.ONE .AND. SCALE( I ).GT.ONE ) THEN
-            IF( SCALE( I ).GE.SFMAX1 / F )
-     $         GO TO 90
-         END IF
-         G = ONE / F
-         SCALE( I ) = SCALE( I )*F
-         NOCONV = .TRUE.
-C
-         CALL DSCAL( N, G, A( I, 1 ), LDA )
-         CALL DSCAL( N, F, A( 1, I ), 1 )
-         IF( M.GT.0 ) CALL DSCAL( M, G, B( I, 1 ), LDB )
-         IF( P.GT.0 ) CALL DSCAL( P, F, C( 1, I ), 1 )
-C
-   90 CONTINUE
-C
-      IF( NOCONV )
-     $   GO TO 30
-C
-C     Set the norm reduction parameter.
-C
-      MAXRED = SNORM
-      SNORM  = ZERO
-C
-      DO 100 J = 1, N
-         CO = DASUM( N, A( 1, J ), 1 )
-         IF( WITHC .AND. P.GT.0 )
-     $      CO = CO + DASUM( P, C( 1, J ), 1 )
-         SNORM = MAX( SNORM, CO )
-  100 CONTINUE
-C
-      IF( WITHB ) THEN
-C
-         DO 110 J = 1, M
-            SNORM = MAX( SNORM, DASUM( N, B( 1, J ), 1 ) )
-  110    CONTINUE
-C
-      END IF
-      MAXRED = MAXRED/SNORM
-      RETURN
-C *** Last line of TB01ID ***
-      END
--- a/extra/control-devel/src/TB01KD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,334 +0,0 @@
-      SUBROUTINE TB01KD( DICO, STDOM, JOBA, N, M, P, ALPHA, A, LDA, B,
-     $                   LDB, C, LDC, NDIM, U, LDU, WR, WI, DWORK,
-     $                   LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To compute an additive spectral decomposition of the transfer-
-C     function matrix of the system (A,B,C) by reducing the system
-C     state-matrix A to a block-diagonal form.
-C     The system matrices are transformed as
-C     A <-- inv(U)*A*U, B <--inv(U)*B and C <-- C*U.
-C     The leading diagonal block of the resulting A has eigenvalues
-C     in a suitably defined domain of interest.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     STDOM   CHARACTER*1
-C             Specifies whether the domain of interest is of stability
-C             type (left part of complex plane or inside of a circle)
-C             or of instability type (right part of complex plane or
-C             outside of a circle) as follows:
-C             = 'S':  stability type domain;
-C             = 'U':  instability type domain.
-C
-C     JOBA    CHARACTER*1
-C             Specifies the shape of the state dynamics matrix on entry
-C             as follows:
-C             = 'S':  A is in an upper real Schur form;
-C             = 'G':  A is a general square dense matrix.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the state-space representation,
-C             i.e. the order of the matrix A.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs, or of columns of B.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The number of system outputs, or of rows of C.  P >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION.
-C             Specifies the boundary of the domain of interest for the
-C             eigenvalues of A. For a continuous-time system
-C             (DICO = 'C'), ALPHA is the boundary value for the real
-C             parts of eigenvalues, while for a discrete-time system
-C             (DICO = 'D'), ALPHA >= 0 represents the boundary value for
-C             the moduli of eigenvalues.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the unreduced state dynamics matrix A.
-C             If JOBA = 'S' then A must be a matrix in real Schur form.
-C             On exit, the leading N-by-N part of this array contains a
-C             block diagonal matrix inv(U) * A * U with two diagonal
-C             blocks in real Schur form with the elements below the
-C             first subdiagonal set to zero.
-C             The leading NDIM-by-NDIM block of A has eigenvalues in the
-C             domain of interest and the trailing (N-NDIM)-by-(N-NDIM)
-C             block has eigenvalues outside the domain of interest.
-C             The domain of interest for lambda(A), the eigenvalues
-C             of A, is defined by the parameters ALPHA, DICO and STDOM
-C             as follows:
-C             For a continuous-time system (DICO = 'C'):
-C               Real(lambda(A)) < ALPHA if STDOM = 'S';
-C               Real(lambda(A)) > ALPHA if STDOM = 'U';
-C             For a discrete-time system (DICO = 'D'):
-C               Abs(lambda(A)) < ALPHA if STDOM = 'S';
-C               Abs(lambda(A)) > ALPHA if STDOM = 'U'.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input matrix B.
-C             On exit, the leading N-by-M part of this array contains
-C             the transformed input matrix inv(U) * B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the output matrix C.
-C             On exit, the leading P-by-N part of this array contains
-C             the transformed output matrix C * U.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     NDIM    (output) INTEGER
-C             The number of eigenvalues of A lying inside the domain of
-C             interest for eigenvalues.
-C
-C     U       (output) DOUBLE PRECISION array, dimension (LDU,N)
-C             The leading N-by-N part of this array contains the
-C             transformation matrix used to reduce A to the block-
-C             diagonal form. The first NDIM columns of U span the
-C             invariant subspace of A corresponding to the eigenvalues
-C             of its leading diagonal block. The last N-NDIM columns
-C             of U span the reducing subspace of A corresponding to
-C             the eigenvalues of the trailing diagonal block of A.
-C
-C     LDU     INTEGER
-C             The leading dimension of array U.  LDU >= max(1,N).
-C
-C     WR, WI  (output) DOUBLE PRECISION arrays, dimension (N)
-C             WR and WI contain the real and imaginary parts,
-C             respectively, of the computed eigenvalues of A. The
-C             eigenvalues will be in the same order that they appear on
-C             the diagonal of the output real Schur form of A. Complex
-C             conjugate pairs of eigenvalues will appear consecutively
-C             with the eigenvalue having the positive imaginary part
-C             first.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The dimension of working array DWORK.
-C             LDWORK >= MAX(1,N)   if JOBA = 'S';
-C             LDWORK >= MAX(1,3*N) if JOBA = 'G'.
-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: the QR algorithm failed to compute all the
-C                  eigenvalues of A;
-C             = 2: a failure occured during the ordering of the real
-C                  Schur form of A;
-C             = 3: the separation of the two diagonal blocks failed
-C                  because of very close eigenvalues.
-C
-C     METHOD
-C
-C     A similarity transformation U is determined that reduces the
-C     system state-matrix A to a block-diagonal form (with two diagonal
-C     blocks), so that the leading diagonal block of the resulting A has
-C     eigenvalues in a specified domain of the complex plane. The
-C     determined transformation is applied to the system (A,B,C) as
-C       A <-- inv(U)*A*U, B <-- inv(U)*B and C <-- C*U.
-C
-C     REFERENCES
-C
-C     [1] Safonov, M.G., Jonckheere, E.A., Verma, M., Limebeer, D.J.N.
-C         Synthesis of positive real multivariable feedback systems.
-C         Int. J. Control, pp. 817-842, 1987.
-C
-C     NUMERICAL ASPECTS
-C                                     3
-C     The algorithm requires about 14N  floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, March 1998.
-C     Based on the RASP routine SADSDC.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Invariant subspace, real Schur form, similarity transformation,
-C     spectral factorization.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION ZERO, ONE
-      PARAMETER        ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER        DICO, JOBA, STDOM
-      INTEGER          INFO, LDA, LDB, LDC, LDU, LDWORK, M, N, NDIM, P
-      DOUBLE PRECISION ALPHA
-C     .. Array Arguments ..
-      DOUBLE PRECISION A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*), U(LDU,*),
-     $                 WI(*), WR(*)
-C     .. Local Scalars ..
-      LOGICAL          DISCR, LJOBG
-      INTEGER          NDIM1, NR
-      DOUBLE PRECISION SCALE
-C     .. External Functions ..
-      LOGICAL          LSAME
-      EXTERNAL         LSAME
-C     .. External Subroutines ..
-      EXTERNAL         DGEMM, DLASET, DTRSYL, TB01LD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC        MAX
-C
-C     .. Executable Statements ..
-C
-      INFO = 0
-      DISCR = LSAME( DICO, 'D' )
-      LJOBG = LSAME( JOBA, 'G' )
-C
-C     Check input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( LSAME( STDOM, 'S' ) .OR.
-     $                 LSAME( STDOM, 'U' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( LSAME( JOBA, 'S' ) .OR. LJOBG ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( DISCR .AND. ALPHA.LT.ZERO ) THEN
-         INFO = -7
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -13
-      ELSE IF( LDU.LT.MAX( 1, N ) ) THEN
-         INFO = -16
-      ELSE IF( LDWORK.LT.MAX( 1,   N ) .OR.
-     $         LDWORK.LT.MAX( 1, 3*N ) .AND. LJOBG ) THEN
-         INFO = -20
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'TB01KD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      NDIM = 0
-      IF( N.EQ.0 )
-     $   RETURN
-C
-C     Reduce A to an ordered real Schur form using an orthogonal
-C     similarity transformation A <- U'*A*U and accumulate the
-C     transformations in U. The reordering of the real Schur form of A
-C     is performed in accordance with the values of the parameters DICO,
-C     STDOM and ALPHA. Apply the transformation to B and C: B <- U'*B
-C     and C <- C*U. The eigenvalues of A are computed in (WR,WI).
-C
-C     Workspace:  need   3*N (if JOBA = 'G'), or N (if JOBA = 'S');
-C                 prefer larger.
-C
-      CALL TB01LD( DICO, STDOM, JOBA, N, M, P, ALPHA, A, LDA, B, LDB, C,
-     $             LDC, NDIM, U, LDU, WR, WI, DWORK, LDWORK, INFO )
-C
-      IF ( INFO.NE.0 )
-     $    RETURN
-C
-      IF ( NDIM.GT.0 .AND. NDIM.LT.N ) THEN
-C
-C        Reduce A to a block-diagonal form by a similarity
-C        transformation of the form
-C               -1                  ( I -X )
-C         A <- T  AT,  where    T = (      )  and X satisfies the
-C                                   ( 0  I )
-C        Sylvester equation
-C
-C          A11*X - X*A22 = A12.
-C
-         NR = N - NDIM
-         NDIM1 = NDIM + 1
-         CALL DTRSYL( 'N', 'N', -1, NDIM, NR, A, LDA, A(NDIM1,NDIM1),
-     $                LDA, A(1,NDIM1), LDA, SCALE, INFO )
-         IF ( INFO.NE.0 ) THEN
-            INFO = 3
-            RETURN
-         END IF
-C                      -1
-C        Compute B <- T  B,  C <- CT,  U <- UT.
-C
-         SCALE = ONE/SCALE
-         CALL DGEMM( 'N', 'N', NDIM, M, NR, SCALE, A(1,NDIM1), LDA,
-     $               B(NDIM1,1), LDB, ONE, B, LDB )
-         CALL DGEMM( 'N', 'N', P, NR, NDIM, -SCALE, C, LDC, A(1,NDIM1),
-     $               LDA, ONE, C(1,NDIM1), LDC )
-         CALL DGEMM( 'N', 'N', N, NR, NDIM, -SCALE, U, LDU, A(1,NDIM1),
-     $               LDA, ONE, U(1,NDIM1), LDU )
-C
-C        Set A12 to zero.
-C
-         CALL DLASET( 'Full', NDIM, NR, ZERO, ZERO, A(1,NDIM1), LDA )
-      END IF
-C
-C     Set to zero the lower triangular part under the first subdiagonal
-C     of A.
-C
-      IF ( N.GT.2 )
-     $   CALL DLASET( 'L', N-2, N-2, ZERO, ZERO, A( 3, 1 ), LDA )
-      RETURN
-C *** Last line of TB01KD ***
-      END
--- a/extra/control-devel/src/TB01LD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,348 +0,0 @@
-      SUBROUTINE TB01LD( DICO, STDOM, JOBA, N, M, P, ALPHA, A, LDA, B,
-     $                   LDB, C, LDC, NDIM, U, LDU, WR, WI, DWORK,
-     $                   LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To reduce the system state matrix A to an ordered upper real
-C     Schur form by using an orthogonal similarity transformation
-C     A <-- U'*A*U and to apply the transformation to the matrices
-C     B and C: B <-- U'*B and C <-- C*U.
-C     The leading block of the resulting A has eigenvalues in a
-C     suitably defined domain of interest.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     DICO    CHARACTER*1
-C             Specifies the type of the system as follows:
-C             = 'C':  continuous-time system;
-C             = 'D':  discrete-time system.
-C
-C     STDOM   CHARACTER*1
-C             Specifies whether the domain of interest is of stability
-C             type (left part of complex plane or inside of a circle)
-C             or of instability type (right part of complex plane or
-C             outside of a circle) as follows:
-C             = 'S':  stability type domain;
-C             = 'U':  instability type domain.
-C
-C     JOBA    CHARACTER*1
-C             Specifies the shape of the state dynamics matrix on entry
-C             as follows:
-C             = 'S':  A is in an upper real Schur form;
-C             = 'G':  A is a general square dense matrix.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the state-space representation,
-C             i.e. the order of the matrix A.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs, or of columns of B.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The number of system outputs, or of rows of C.  P >= 0.
-C
-C     ALPHA   (input) DOUBLE PRECISION.
-C             Specifies the boundary of the domain of interest for the
-C             eigenvalues of A. For a continuous-time system
-C             (DICO = 'C'), ALPHA is the boundary value for the real
-C             parts of eigenvalues, while for a discrete-time system
-C             (DICO = 'D'), ALPHA >= 0 represents the boundary value
-C             for the moduli of eigenvalues.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the unreduced state dynamics matrix A.
-C             If JOBA = 'S' then A must be a matrix in real Schur form.
-C             On exit, the leading N-by-N part of this array contains
-C             the ordered real Schur matrix U' * A * U with the elements
-C             below the first subdiagonal set to zero.
-C             The leading NDIM-by-NDIM part of A has eigenvalues in the
-C             domain of interest and the trailing (N-NDIM)-by-(N-NDIM)
-C             part has eigenvalues outside the domain of interest.
-C             The domain of interest for lambda(A), the eigenvalues
-C             of A, is defined by the parameters ALPHA, DICO and STDOM
-C             as follows:
-C             For a continuous-time system (DICO = 'C'):
-C               Real(lambda(A)) < ALPHA if STDOM = 'S';
-C               Real(lambda(A)) > ALPHA if STDOM = 'U';
-C             For a discrete-time system (DICO = 'D'):
-C               Abs(lambda(A)) < ALPHA if STDOM = 'S';
-C               Abs(lambda(A)) > ALPHA if STDOM = 'U'.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input matrix B.
-C             On exit, the leading N-by-M part of this array contains
-C             the transformed input matrix U' * B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the output matrix C.
-C             On exit, the leading P-by-N part of this array contains
-C             the transformed output matrix C * U.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     NDIM    (output) INTEGER
-C             The number of eigenvalues of A lying inside the domain of
-C             interest for eigenvalues.
-C
-C     U       (output) DOUBLE PRECISION array, dimension (LDU,N)
-C             The leading N-by-N part of this array contains the
-C             orthogonal transformation matrix used to reduce A to the
-C             real Schur form and/or to reorder the diagonal blocks of
-C             real Schur form of A. The first NDIM columns of U form
-C             an orthogonal basis for the invariant subspace of A
-C             corresponding to the first NDIM eigenvalues.
-C
-C     LDU     INTEGER
-C             The leading dimension of array U.  LDU >= max(1,N).
-C
-C     WR, WI  (output) DOUBLE PRECISION arrays, dimension (N)
-C             WR and WI contain the real and imaginary parts,
-C             respectively, of the computed eigenvalues of A. The
-C             eigenvalues will be in the same order that they appear on
-C             the diagonal of the output real Schur form of A. Complex
-C             conjugate pairs of eigenvalues will appear consecutively
-C             with the eigenvalue having the positive imaginary part
-C             first.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The dimension of working array DWORK.
-C             LDWORK >= MAX(1,N)   if JOBA = 'S';
-C             LDWORK >= MAX(1,3*N) if JOBA = 'G'.
-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: the QR algorithm failed to compute all the
-C                  eigenvalues of A;
-C             = 2: a failure occured during the ordering of the real
-C                  Schur form of A.
-C
-C     METHOD
-C
-C     Matrix A is reduced to an ordered upper real Schur form using an
-C     orthogonal similarity transformation A <-- U'*A*U. This
-C     transformation is determined so that the leading block of the
-C     resulting A has eigenvalues in a suitably defined domain of
-C     interest. Then, the transformation is applied to the matrices B
-C     and C: B <-- U'*B and C <-- C*U.
-C
-C     NUMERICAL ASPECTS
-C                                     3
-C     The algorithm requires about 14N  floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, March 1998.
-C     Based on the RASP routine SRSFOD.
-C
-C     REVISIONS
-C
-C     V. Sima, Research Institute for Informatics, Bucharest, Oct. 2001.
-C
-C     KEYWORDS
-C
-C     Invariant subspace, orthogonal transformation, real Schur form,
-C     similarity transformation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION ZERO, ONE
-      PARAMETER        ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER        DICO, JOBA, STDOM
-      INTEGER          INFO, LDA, LDB, LDC, LDU, LDWORK, M, N, NDIM, P
-      DOUBLE PRECISION ALPHA
-C     .. Array Arguments ..
-      DOUBLE PRECISION A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*), U(LDU,*),
-     $                 WI(*), WR(*)
-C     .. Local Scalars ..
-      LOGICAL          DISCR, LJOBG
-      INTEGER          I, IERR, LDWP, SDIM
-      DOUBLE PRECISION WRKOPT
-C     .. Local Arrays ..
-      LOGICAL          BWORK( 1 )
-C     .. External Functions ..
-      LOGICAL          LSAME, SELECT
-      EXTERNAL         LSAME, SELECT
-C     .. External Subroutines ..
-      EXTERNAL         DCOPY, DGEES, DGEMM, DGEMV, DLACPY, DLASET,
-     $                 MB03QD, MB03QX, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC        DBLE, MAX
-C
-C     .. Executable Statements ..
-C
-      INFO = 0
-      DISCR = LSAME( DICO, 'D' )
-      LJOBG = LSAME( JOBA, 'G' )
-C
-C     Check input scalar arguments.
-C
-      IF( .NOT. ( LSAME( DICO, 'C' ) .OR. DISCR ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT. ( LSAME( STDOM, 'S' ) .OR.
-     $                 LSAME( STDOM, 'U' ) ) ) THEN
-         INFO = -2
-      ELSE IF( .NOT. ( LSAME( JOBA, 'S' ) .OR. LJOBG ) ) THEN
-         INFO = -3
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -6
-      ELSE IF( DISCR .AND. ALPHA.LT.ZERO ) THEN
-         INFO = -7
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -13
-      ELSE IF( LDU.LT.MAX( 1, N ) ) THEN
-         INFO = -16
-      ELSE IF( LDWORK.LT.MAX( 1,   N ) .OR.
-     $         LDWORK.LT.MAX( 1, 3*N ) .AND. LJOBG ) THEN
-         INFO = -20
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'TB01LD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      NDIM = 0
-      IF( N.EQ.0 )
-     $   RETURN
-C
-      IF( LSAME( JOBA, 'G' ) ) THEN
-C
-C        Reduce A to real Schur form using an orthogonal similarity
-C        transformation A <- U'*A*U, accumulate the transformation in U
-C        and compute the eigenvalues of A in (WR,WI).
-C
-C        Workspace:  need   3*N;
-C                    prefer larger.
-C
-         CALL DGEES( 'Vectors', 'Not ordered', SELECT, N, A, LDA, SDIM,
-     $               WR, WI, U, LDU, DWORK, LDWORK, BWORK, INFO )
-         WRKOPT = DWORK( 1 )
-         IF( INFO.NE.0 ) THEN
-            INFO = 1
-            RETURN
-         END IF
-      ELSE
-C
-C        Initialize U with an identity matrix.
-C
-         CALL DLASET( 'Full', N, N, ZERO, ONE, U, LDU )
-         WRKOPT = 0
-      END IF
-C
-C     Separate the spectrum of A. The leading NDIM-by-NDIM submatrix of
-C     A corresponds to the eigenvalues of interest.
-C     Workspace:  need   N.
-C
-      CALL MB03QD( DICO, STDOM, 'Update', N, 1, N, ALPHA, A, LDA,
-     $             U, LDU, NDIM, DWORK, INFO )
-      IF( INFO.NE.0 )
-     $   RETURN
-C
-C     Compute the eigenvalues.
-C
-      CALL MB03QX( N, A, LDA, WR, WI, IERR )
-C
-C     Apply the transformation: B <-- U'*B.
-C
-      IF( LDWORK.LT.N*M ) THEN
-C
-C        Not enough working space for using DGEMM.
-C
-         DO 10 I = 1, M
-            CALL DCOPY( N, B(1,I), 1, DWORK, 1 )
-            CALL DGEMV( 'Transpose', N, N, ONE, U, LDU, DWORK, 1, ZERO,
-     $                  B(1,I), 1 )
-   10    CONTINUE
-C
-      ELSE
-         CALL DLACPY( 'Full', N, M, B, LDB, DWORK, N )
-         CALL DGEMM( 'Transpose', 'No transpose', N, M, N, ONE, U, LDU,
-     $               DWORK, N, ZERO, B, LDB )
-         WRKOPT = MAX( WRKOPT, DBLE( N*M ) )
-      END IF
-C
-C     Apply the transformation: C <-- C*U.
-C
-      IF( LDWORK.LT.N*P ) THEN
-C
-C        Not enough working space for using DGEMM.
-C
-         DO 20 I = 1, P
-            CALL DCOPY( N, C(I,1), LDC, DWORK, 1 )
-            CALL DGEMV( 'Transpose', N, N, ONE, U, LDU, DWORK, 1, ZERO,
-     $                  C(I,1), LDC )
-   20    CONTINUE
-C
-      ELSE
-         LDWP = MAX( 1, P )
-         CALL DLACPY( 'Full', P, N, C, LDC, DWORK, LDWP )
-         CALL DGEMM( 'No transpose', 'No transpose', P, N, N, ONE,
-     $               DWORK, LDWP, U, LDU, ZERO, C, LDC )
-         WRKOPT = MAX( WRKOPT, DBLE( N*P ) )
-      END IF
-C
-      DWORK( 1 ) = WRKOPT
-C
-      RETURN
-C *** Last line of TB01LD ***
-      END
--- a/extra/control-devel/src/TB01PD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,352 +0,0 @@
-      SUBROUTINE TB01PD( JOB, EQUIL, N, M, P, A, LDA, B, LDB, C, LDC,
-     $                   NR, TOL, IWORK, DWORK, LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To find a reduced (controllable, observable, or minimal) state-
-C     space representation (Ar,Br,Cr) for any original state-space
-C     representation (A,B,C). The matrix Ar is in upper block
-C     Hessenberg form.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOB     CHARACTER*1
-C             Indicates whether the user wishes to remove the
-C             uncontrollable and/or unobservable parts as follows:
-C             = 'M':  Remove both the uncontrollable and unobservable
-C                     parts to get a minimal state-space representation;
-C             = 'C':  Remove the uncontrollable part only to get a
-C                     controllable state-space representation;
-C             = 'O':  Remove the unobservable part only to get an
-C                     observable state-space representation.
-C
-C     EQUIL   CHARACTER*1
-C             Specifies whether the user wishes to preliminarily balance
-C             the triplet (A,B,C) as follows:
-C             = 'S':  Perform balancing (scaling);
-C             = 'N':  Do not perform balancing.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation, i.e.
-C             the order of the matrix A.  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     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the original state dynamics matrix A.
-C             On exit, the leading NR-by-NR part of this array contains
-C             the upper block Hessenberg state dynamics matrix Ar of a
-C             minimal, controllable, or observable realization for the
-C             original system, depending on the value of JOB, JOB = 'M',
-C             JOB = 'C', or JOB = 'O', respectively.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M),
-C             if JOB = 'C', or (LDB,MAX(M,P)), otherwise.
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B; if JOB = 'M',
-C             or JOB = 'O', the remainder of the leading N-by-MAX(M,P)
-C             part is used as internal workspace.
-C             On exit, the leading NR-by-M part of this array contains
-C             the transformed input/state matrix Br of a minimal,
-C             controllable, or observable realization for the original
-C             system, depending on the value of JOB, JOB = 'M',
-C             JOB = 'C', or JOB = 'O', respectively.
-C             If JOB = 'C', only the first IWORK(1) rows of B are
-C             nonzero.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C; if JOB = 'M',
-C             or JOB = 'O', the remainder of the leading MAX(M,P)-by-N
-C             part is used as internal workspace.
-C             On exit, the leading P-by-NR part of this array contains
-C             the transformed state/output matrix Cr of a minimal,
-C             controllable, or observable realization for the original
-C             system, depending on the value of JOB, JOB = 'M',
-C             JOB = 'C', or JOB = 'O', respectively.
-C             If JOB = 'M', or JOB = 'O', only the last IWORK(1) columns
-C             (in the first NR columns) of C are nonzero.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.
-C             LDC >= MAX(1,M,P) if N > 0.
-C             LDC >= 1          if N = 0.
-C
-C     NR      (output) INTEGER
-C             The order of the reduced state-space representation
-C             (Ar,Br,Cr) of a minimal, controllable, or observable
-C             realization for the original system, depending on
-C             JOB = 'M', JOB = 'C', or JOB = 'O'.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used in rank determination when
-C             transforming (A, B, C). If the user sets TOL > 0, then
-C             the given value of TOL is used as a lower bound for the
-C             reciprocal condition number (see the description of the
-C             argument RCOND in the SLICOT routine MB03OD);  a
-C             (sub)matrix whose estimated condition number is less than
-C             1/TOL is considered to be of full rank.  If the user sets
-C             TOL <= 0, then an implicitly computed, default tolerance
-C             (determined by the SLICOT routine TB01UD) is used instead.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N+MAX(M,P))
-C             On exit, if INFO = 0, the first nonzero elements of
-C             IWORK(1:N) return the orders of the diagonal blocks of A.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1, N + MAX(N, 3*M, 3*P)).
-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
-C     METHOD
-C
-C     If JOB = 'M', the matrices A and B are operated on by orthogonal
-C     similarity transformations (made up of products of Householder
-C     transformations) so as to produce an upper block Hessenberg matrix
-C     A1 and a matrix B1 with all but its first rank(B) rows zero; this
-C     separates out the controllable part of the original system.
-C     Applying the same algorithm to the dual of this subsystem,
-C     therefore separates out the controllable and observable (i.e.
-C     minimal) part of the original system representation, with the
-C     final Ar upper block Hessenberg (after using pertransposition).
-C     If JOB = 'C', or JOB = 'O', only the corresponding part of the
-C     above procedure is applied.
-C
-C     REFERENCES
-C
-C     [1] Van Dooren, P.
-C         The Generalized Eigenstructure Problem in Linear System
-C         Theory. (Algorithm 1)
-C         IEEE Trans. Auto. Contr., AC-26, pp. 111-129, 1981.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations and is backward stable.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1998.
-C
-C     REVISIONS
-C
-C     A. Varga, DLR Oberpfaffenhofen, July 1998.
-C     A. Varga, DLR Oberpfaffenhofen, April 28, 1999.
-C     V. Sima, Research Institute for Informatics, Bucharest, Mar. 2004.
-C
-C     KEYWORDS
-C
-C     Hessenberg form, minimal realization, multivariable system,
-C     orthogonal transformation, state-space model, state-space
-C     representation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      INTEGER           LDIZ
-      PARAMETER         ( LDIZ = 1 )
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         EQUIL, JOB
-      INTEGER           INFO, LDA, LDB, LDC, LDWORK, M, N, NR, P
-      DOUBLE PRECISION  TOL
-C     .. Array Arguments ..
-      INTEGER           IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*)
-C     .. Local Scalars ..
-      LOGICAL           LEQUIL, LNJOBC, LNJOBO
-      INTEGER           I, INDCON, ITAU, IZ, JWORK, KL, MAXMP, NCONT,
-     $                  WRKOPT
-      DOUBLE PRECISION  MAXRED
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          AB07MD, TB01ID, TB01UD, TB01XD, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         INT, MAX, MIN
-C     .. Executable Statements ..
-C
-      INFO = 0
-      MAXMP = MAX( M, P )
-      LNJOBC = .NOT.LSAME( JOB,   'C' )
-      LNJOBO = .NOT.LSAME( JOB,   'O' )
-      LEQUIL =      LSAME( EQUIL, 'S' )
-C
-C     Test the input scalar arguments.
-C
-      IF( LNJOBC .AND. LNJOBO .AND. .NOT.LSAME( JOB, 'M' ) ) THEN
-         INFO = -1
-      ELSE IF( .NOT.LEQUIL .AND. .NOT.LSAME( EQUIL, 'N' ) ) THEN
-         INFO = -2
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -5
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -9
-      ELSE IF( LDC.LT.1 .OR. ( N.GT.0 .AND. LDC.LT.MAXMP ) ) THEN
-         INFO = -11
-      ELSE IF( LDWORK.LT.MAX( 1, N + MAX( N, 3*MAXMP ) ) ) THEN
-         INFO = -16
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'TB01PD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( N.EQ.0 .OR. ( LNJOBC .AND. MIN( N, P ).EQ.0 ) .OR.
-     $                 ( LNJOBO .AND. MIN( N, M ).EQ.0 ) ) THEN
-         NR = 0
-C
-         DO 5 I = 1, N
-            IWORK(I) = 0
-    5    CONTINUE
-C
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     If required, balance the triplet (A,B,C) (default MAXRED).
-C     Workspace: need N.
-C
-C     (Note: Comments in the code beginning "Workspace:" describe the
-C     minimal amount of real workspace needed at that point in the code,
-C     as well as the preferred amount for good performance.)
-C
-      IF ( LEQUIL ) THEN
-         MAXRED = ZERO
-         CALL TB01ID( 'A', N, M, P, MAXRED, A, LDA, B, LDB, C, LDC,
-     $                DWORK, INFO )
-         WRKOPT = N
-      ELSE
-         WRKOPT = 1
-      END IF
-C
-      IZ    = 1
-      ITAU  = 1
-      JWORK = ITAU + N
-      IF ( LNJOBO ) THEN
-C
-C        Separate out controllable subsystem (of order NCONT):
-C        A <-- Z'*A*Z,  B <-- Z'*B,  C <-- C*Z.
-C
-C        Workspace: need   N + MAX(N, 3*M, P).
-C                   prefer larger.
-C
-         CALL TB01UD( 'No Z', N, M, P, A, LDA, B, LDB, C, LDC, NCONT,
-     $                INDCON, IWORK, DWORK(IZ), LDIZ, DWORK(ITAU), TOL,
-     $                IWORK(N+1), DWORK(JWORK), LDWORK-JWORK+1, INFO )
-C
-         WRKOPT = INT( DWORK(JWORK) ) + JWORK - 1
-      ELSE
-         NCONT = N
-      END IF
-C
-      IF ( LNJOBC ) THEN
-C
-C        Separate out the observable subsystem (of order NR):
-C        Form the dual of the subsystem of order NCONT (which is
-C        controllable, if JOB = 'M'), leaving rest as it is.
-C
-         CALL AB07MD( 'Z', NCONT, M, P, A, LDA, B, LDB, C, LDC, DWORK,
-     $                1, INFO )
-C
-C        And separate out the controllable part of this dual subsystem.
-C
-C        Workspace: need   NCONT + MAX(NCONT, 3*P, M).
-C                   prefer larger.
-C
-         CALL TB01UD( 'No Z', NCONT, P, M, A, LDA, B, LDB, C, LDC, NR,
-     $                INDCON, IWORK, DWORK(IZ), LDIZ, DWORK(ITAU), TOL,
-     $                IWORK(N+1), DWORK(JWORK), LDWORK-JWORK+1, INFO )
-C
-         WRKOPT = MAX( WRKOPT, INT( DWORK(JWORK) )+JWORK-1 )
-C
-C        Transpose and reorder (to get a block upper Hessenberg
-C        matrix A), giving, for JOB = 'M', the controllable and
-C        observable (i.e., minimal) part of original system.
-C
-         IF( INDCON.GT.0 ) THEN
-            KL = IWORK(1) - 1
-            IF ( INDCON.GE.2 )
-     $         KL = KL + IWORK(2)
-         ELSE
-            KL = 0
-         END IF
-         CALL TB01XD( 'Zero D', NR, P, M, KL, MAX( 0, NR-1 ), A, LDA,
-     $                B, LDB, C, LDC, DWORK, 1, INFO )
-      ELSE
-         NR = NCONT
-      END IF
-C
-C     Annihilate the trailing components of IWORK(1:N).
-C
-      DO 10 I = INDCON + 1, N
-         IWORK(I) = 0
-   10 CONTINUE
-C
-C     Set optimal workspace dimension.
-C
-      DWORK(1) = WRKOPT
-      RETURN
-C *** Last line of TB01PD ***
-      END
--- a/extra/control-devel/src/TB01UD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,491 +0,0 @@
-      SUBROUTINE TB01UD( JOBZ, N, M, P, A, LDA, B, LDB, C, LDC, NCONT,
-     $                   INDCON, NBLK, Z, LDZ, TAU, TOL, IWORK, DWORK,
-     $                   LDWORK, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To find a controllable realization for the linear time-invariant
-C     multi-input system
-C
-C             dX/dt = A * X + B * U,
-C                Y  = C * X,
-C
-C     where A, B, and C are N-by-N, N-by-M, and P-by-N matrices,
-C     respectively, and A and B are reduced by this routine to
-C     orthogonal canonical form using (and optionally accumulating)
-C     orthogonal similarity transformations, which are also applied
-C     to C.  Specifically, the system (A, B, C) is reduced to the
-C     triplet (Ac, Bc, Cc), where Ac = Z' * A * Z, Bc = Z' * B,
-C     Cc = C * Z,  with
-C
-C             [ Acont     *    ]         [ Bcont ]
-C        Ac = [                ],   Bc = [       ],
-C             [   0    Auncont ]         [   0   ]
-C
-C        and
-C
-C                [ A11 A12  . . .  A1,p-1 A1p ]         [ B1 ]
-C                [ A21 A22  . . .  A2,p-1 A2p ]         [ 0  ]
-C                [  0  A32  . . .  A3,p-1 A3p ]         [ 0  ]
-C        Acont = [  .   .   . . .    .     .  ],   Bc = [ .  ],
-C                [  .   .     . .    .     .  ]         [ .  ]
-C                [  .   .       .    .     .  ]         [ .  ]
-C                [  0   0   . . .  Ap,p-1 App ]         [ 0  ]
-C
-C     where the blocks  B1, A21, ..., Ap,p-1  have full row ranks and
-C     p is the controllability index of the pair.  The size of the
-C     block  Auncont is equal to the dimension of the uncontrollable
-C     subspace of the pair (A, B).
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBZ    CHARACTER*1
-C             Indicates whether the user wishes to accumulate in a
-C             matrix Z the orthogonal similarity transformations for
-C             reducing the system, as follows:
-C             = 'N':  Do not form Z and do not store the orthogonal
-C                     transformations;
-C             = 'F':  Do not form Z, but store the orthogonal
-C                     transformations in the factored form;
-C             = 'I':  Z is initialized to the unit matrix and the
-C                     orthogonal transformation matrix Z is returned.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation,
-C             i.e. the order of the matrix A.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs, or of columns of B.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The number of system outputs, or of rows of C.  P >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the original state dynamics matrix A.
-C             On exit, the leading NCONT-by-NCONT part contains the
-C             upper block Hessenberg state dynamics matrix Acont in Ac,
-C             given by Z' * A * Z, of a controllable realization for
-C             the original system. The elements below the first block-
-C             subdiagonal are set to zero. The leading N-by-N part
-C             contains the matrix Ac.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input matrix B.
-C             On exit, the leading NCONT-by-M part of this array
-C             contains the transformed input matrix Bcont in Bc, given
-C             by Z' * B, with all elements but the first block set to
-C             zero. The leading N-by-M part contains the matrix Bc.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the output matrix C.
-C             On exit, the leading P-by-N part of this array contains
-C             the transformed output matrix Cc, given by C * Z.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     NCONT   (output) INTEGER
-C             The order of the controllable state-space representation.
-C
-C     INDCON  (output) INTEGER
-C             The controllability index of the controllable part of the
-C             system representation.
-C
-C     NBLK    (output) INTEGER array, dimension (N)
-C             The leading INDCON elements of this array contain the
-C             the orders of the diagonal blocks of Acont.
-C
-C     Z       (output) DOUBLE PRECISION array, dimension (LDZ,N)
-C             If JOBZ = 'I', then the leading N-by-N part of this
-C             array contains the matrix of accumulated orthogonal
-C             similarity transformations which reduces the given system
-C             to orthogonal canonical form.
-C             If JOBZ = 'F', the elements below the diagonal, with the
-C             array TAU, represent the orthogonal transformation matrix
-C             as a product of elementary reflectors. The transformation
-C             matrix can then be obtained by calling the LAPACK Library
-C             routine DORGQR.
-C             If JOBZ = 'N', the array Z is not referenced and can be
-C             supplied as a dummy array (i.e. set parameter LDZ = 1 and
-C             declare this array to be Z(1,1) in the calling program).
-C
-C     LDZ     INTEGER
-C             The leading dimension of array Z. If JOBZ = 'I' or
-C             JOBZ = 'F', LDZ >= MAX(1,N); if JOBZ = 'N', LDZ >= 1.
-C
-C     TAU     (output) DOUBLE PRECISION array, dimension (N)
-C             The elements of TAU contain the scalar factors of the
-C             elementary reflectors used in the reduction of B and A.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used in rank determination when
-C             transforming (A, B). If the user sets TOL > 0, then
-C             the given value of TOL is used as a lower bound for the
-C             reciprocal condition number (see the description of the
-C             argument RCOND in the SLICOT routine MB03OD);  a
-C             (sub)matrix whose estimated condition number is less than
-C             1/TOL is considered to be of full rank.  If the user sets
-C             TOL <= 0, then an implicitly computed, default tolerance,
-C             defined by  TOLDEF = N*N*EPS,  is used instead, where EPS
-C             is the machine precision (see LAPACK Library routine
-C             DLAMCH).
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (M)
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1, N, 3*M, P).
-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
-C     METHOD
-C
-C     Matrix B is first QR-decomposed and the appropriate orthogonal
-C     similarity transformation applied to the matrix A. Leaving the
-C     first rank(B) states unchanged, the remaining lower left block
-C     of A is then QR-decomposed and the new orthogonal matrix, Q1,
-C     is also applied to the right of A to complete the similarity
-C     transformation. By continuing in this manner, a completely
-C     controllable state-space pair (Acont, Bcont) is found for the
-C     given (A, B), where Acont is upper block Hessenberg with each
-C     subdiagonal block of full row rank, and Bcont is zero apart from
-C     its (independent) first rank(B) rows.
-C     All orthogonal transformations determined in this process are also
-C     applied to the matrix C, from the right.
-C     NOTE that the system controllability indices are easily
-C     calculated from the dimensions of the blocks of Acont.
-C
-C     REFERENCES
-C
-C     [1] Konstantinov, M.M., Petkov, P.Hr. and Christov, N.D.
-C         Orthogonal Invariants and Canonical Forms for Linear
-C         Controllable Systems.
-C         Proc. 8th IFAC World Congress, Kyoto, 1, pp. 49-54, 1981.
-C
-C     [2] Paige, C.C.
-C         Properties of numerical algorithms related to computing
-C         controllablity.
-C         IEEE Trans. Auto. Contr., AC-26, pp. 130-138, 1981.
-C
-C     [3] Petkov, P.Hr., Konstantinov, M.M., Gu, D.W. and
-C         Postlethwaite, I.
-C         Optimal Pole Assignment Design of Linear Multi-Input Systems.
-C         Leicester University, Report 99-11, May 1996.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations and is backward stable.
-C
-C     FURTHER COMMENTS
-C
-C     If the system matrices A and B are badly scaled, it would be
-C     useful to scale them with SLICOT routine TB01ID, before calling
-C     the routine.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1998.
-C
-C     REVISIONS
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, May 1999, Nov. 2003.
-C     A. Varga, DLR Oberpfaffenhofen, March 2002, Nov. 2003.
-C
-C     KEYWORDS
-C
-C     Controllability, minimal realization, orthogonal canonical form,
-C     orthogonal transformation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         JOBZ
-      INTEGER           INDCON, INFO, LDA, LDB, LDC, LDWORK, LDZ, M, N,
-     $                  NCONT, P
-      DOUBLE PRECISION  TOL
-C     .. Array Arguments ..
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*), TAU(*),
-     $                  Z(LDZ,*)
-      INTEGER           IWORK(*), NBLK(*)
-C     .. Local Scalars ..
-      LOGICAL           LJOBF, LJOBI, LJOBZ
-      INTEGER           IQR, ITAU, J, MCRT, NBL, NCRT, NI, NJ, RANK,
-     $                  WRKOPT
-      DOUBLE PRECISION  ANORM, BNORM, FNRM, TOLDEF
-C     .. Local Arrays ..
-      DOUBLE PRECISION  SVAL(3)
-C     .. External Functions ..
-      LOGICAL           LSAME
-      DOUBLE PRECISION  DLAMCH, DLANGE, DLAPY2
-      EXTERNAL          DLAMCH, DLANGE, DLAPY2, LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DCOPY, DLACPY, DLAPMT, DLASET, DORGQR, DORMQR,
-     $                  MB01PD, MB03OY, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         DBLE, INT, MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-      INFO = 0
-      LJOBF = LSAME( JOBZ, 'F' )
-      LJOBI = LSAME( JOBZ, 'I' )
-      LJOBZ = LJOBF.OR.LJOBI
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.LJOBZ .AND. .NOT.LSAME( JOBZ, 'N' ) ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -6
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -10
-      ELSE IF( .NOT.LJOBZ .AND. LDZ.LT.1 .OR.
-     $              LJOBZ .AND. LDZ.LT.MAX( 1, N ) ) THEN
-         INFO = -15
-      ELSE IF(  LDWORK.LT.MAX( 1, N, 3*M, P ) ) THEN
-         INFO = -20
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'TB01UD', -INFO )
-         RETURN
-      END IF
-C
-      NCONT  = 0
-      INDCON = 0
-C
-C     Calculate the absolute norms of A and B (used for scaling).
-C
-      ANORM = DLANGE( 'M', N, N, A, LDA, DWORK )
-      BNORM = DLANGE( 'M', N, M, B, LDB, DWORK )
-C
-C     Quick return if possible.
-C
-      IF ( MIN( N, M ).EQ.0 .OR. BNORM.EQ.ZERO ) THEN
-         IF( N.GT.0 ) THEN
-            IF ( LJOBI ) THEN
-               CALL DLASET( 'Full', N, N, ZERO, ONE, Z, LDZ )
-            ELSE IF ( LJOBF ) THEN
-               CALL DLASET( 'Full', N, N, ZERO, ZERO, Z, LDZ )
-               CALL DLASET( 'Full', N, 1, ZERO, ZERO, TAU, N )
-            END IF
-         END IF
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-C     Scale (if needed) the matrices A and B.
-C
-      CALL MB01PD( 'S', 'G', N, N, 0, 0, ANORM, 0, NBLK, A, LDA, INFO )
-      CALL MB01PD( 'S', 'G', N, M, 0, 0, BNORM, 0, NBLK, B, LDB, INFO )
-C
-C     Compute the Frobenius norm of [ B  A ] (used for rank estimation).
-C
-      FNRM = DLAPY2( DLANGE( 'F', N, M, B, LDB, DWORK ),
-     $               DLANGE( 'F', N, N, A, LDA, DWORK ) )
-C
-      TOLDEF = TOL
-      IF ( TOLDEF.LE.ZERO ) THEN
-C
-C        Use the default tolerance in controllability determination.
-C
-         TOLDEF = DBLE( N*N )*DLAMCH( 'EPSILON' )
-      END IF
-C
-      IF ( FNRM.LT.TOLDEF )
-     $   FNRM = ONE
-C
-      WRKOPT = 1
-      NI = 0
-      ITAU = 1
-      NCRT = N
-      MCRT = M
-      IQR  = 1
-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
-   10 CONTINUE
-C
-C        Rank-revealing QR decomposition with column pivoting.
-C        The calculation is performed in NCRT rows of B starting from
-C        the row IQR (initialized to 1 and then set to rank(B)+1).
-C        Workspace: 3*MCRT.
-C
-         CALL MB03OY( NCRT, MCRT, B(IQR,1), LDB, TOLDEF, FNRM, RANK,
-     $                SVAL, IWORK, TAU(ITAU), DWORK, INFO )
-C
-         IF ( RANK.NE.0 ) THEN
-            NJ = NI
-            NI = NCONT
-            NCONT = NCONT + RANK
-            INDCON = INDCON + 1
-            NBLK(INDCON) = RANK
-C
-C           Premultiply and postmultiply the appropriate block row
-C           and block column of A by Q' and Q, respectively.
-C           Workspace: need   NCRT;
-C                      prefer NCRT*NB.
-C
-            CALL DORMQR( 'Left', 'Transpose', NCRT, NCRT, RANK,
-     $                   B(IQR,1), LDB, TAU(ITAU), A(NI+1,NI+1), LDA,
-     $                   DWORK, LDWORK, INFO )
-            WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) )
-C
-C           Workspace: need   N;
-C                      prefer N*NB.
-C
-            CALL DORMQR( 'Right', 'No transpose', N, NCRT, RANK,
-     $                   B(IQR,1), LDB, TAU(ITAU), A(1,NI+1), LDA,
-     $                   DWORK, LDWORK, INFO )
-            WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) )
-C
-C           Postmultiply the appropriate block column of C by Q.
-C           Workspace: need   P;
-C                      prefer P*NB.
-C
-            CALL DORMQR( 'Right', 'No transpose', P, NCRT, RANK,
-     $                   B(IQR,1), LDB, TAU(ITAU), C(1,NI+1), LDC,
-     $                   DWORK, LDWORK, INFO )
-            WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) )
-C
-C           If required, save transformations.
-C
-            IF ( LJOBZ.AND.NCRT.GT.1 ) THEN
-               CALL DLACPY( 'L', NCRT-1, MIN( RANK, NCRT-1 ),
-     $                      B(IQR+1,1), LDB, Z(NI+2,ITAU), LDZ )
-            END IF
-C
-C           Zero the subdiagonal elements of the current matrix.
-C
-            IF ( RANK.GT.1 )
-     $         CALL DLASET( 'L', RANK-1, RANK-1, ZERO, ZERO, B(IQR+1,1),
-     $                      LDB )
-C
-C           Backward permutation of the columns of B or A.
-C
-            IF ( INDCON.EQ.1 ) THEN
-               CALL DLAPMT( .FALSE., RANK, M, B(IQR,1), LDB, IWORK )
-               IQR = RANK + 1
-            ELSE
-               DO 20 J = 1, MCRT
-                  CALL DCOPY( RANK, B(IQR,J), 1, A(NI+1,NJ+IWORK(J)),
-     $                        1 )
-   20          CONTINUE
-            END IF
-C
-            ITAU = ITAU + RANK
-            IF ( RANK.NE.NCRT ) THEN
-               MCRT = RANK
-               NCRT = NCRT - RANK
-               CALL DLACPY( 'G', NCRT, MCRT, A(NCONT+1,NI+1), LDA,
-     $                      B(IQR,1), LDB )
-               CALL DLASET( 'G', NCRT, MCRT, ZERO, ZERO,
-     $                      A(NCONT+1,NI+1), LDA )
-               GO TO 10
-            END IF
-         END IF
-C
-C     If required, accumulate transformations.
-C     Workspace: need N;  prefer N*NB.
-C
-      IF ( LJOBI ) THEN
-         CALL DORGQR( N, N, ITAU-1, Z, LDZ, TAU, DWORK,
-     $                LDWORK, INFO )
-         WRKOPT = MAX( WRKOPT, INT( DWORK(1) ) )
-      END IF
-C
-C     Annihilate the trailing blocks of B.
-C
-      IF( IQR.LE.N )
-     $   CALL DLASET( 'G', N-IQR+1, M, ZERO, ZERO, B(IQR,1), LDB )
-C
-C     Annihilate the trailing elements of TAU, if JOBZ = 'F'.
-C
-      IF ( LJOBF ) THEN
-         DO 30 J = ITAU, N
-            TAU(J) = ZERO
-   30    CONTINUE
-      END IF
-C
-C     Undo scaling of A and B.
-C
-      IF ( INDCON.LT.N ) THEN
-         NBL = INDCON + 1
-         NBLK(NBL) = N - NCONT
-      ELSE
-         NBL = 0
-      END IF
-      CALL MB01PD( 'U', 'H', N, N, 0, 0, ANORM, NBL, NBLK, A, LDA,
-     $             INFO )
-      CALL MB01PD( 'U', 'G', NBLK(1), M, 0, 0, BNORM, 0, NBLK, B, LDB,
-     $             INFO )
-C
-C     Set optimal workspace dimension.
-C
-      DWORK(1) = WRKOPT
-      RETURN
-C *** Last line of TB01UD ***
-      END
--- a/extra/control-devel/src/TB01WD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,259 +0,0 @@
-      SUBROUTINE TB01WD( N, M, P, A, LDA, B, LDB, C, LDC, U, LDU,
-     $                   WR, WI, 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 reduce the system state matrix A to an upper real Schur form
-C     by using an orthogonal similarity transformation A <-- U'*A*U and
-C     to apply the transformation to the matrices B and C: B <-- U'*B
-C     and C <-- C*U.
-C
-C     ARGUMENTS
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the original state-space representation,
-C             i.e. the order of the matrix A.  N >= 0.
-C
-C     M       (input) INTEGER
-C             The number of system inputs, or of columns of B.  M >= 0.
-C
-C     P       (input) INTEGER
-C             The number of system outputs, or of rows of C.  P >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the original state dynamics matrix A.
-C             On exit, the leading N-by-N part of this array contains
-C             the matrix U' * A * U in real Schur form. The elements
-C             below the first subdiagonal are set to zero.
-C             Note:  A matrix is in real Schur form if it is upper
-C                    quasi-triangular with 1-by-1 and 2-by-2 blocks.
-C                    2-by-2 blocks are standardized in the form
-C                             [  a  b  ]
-C                             [  c  a  ]
-C                    where b*c < 0. The eigenvalues of such a block
-C                    are a +- sqrt(bc).
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension (LDB,M)
-C             On entry, the leading N-by-M part of this array must
-C             contain the input matrix B.
-C             On exit, the leading N-by-M part of this array contains
-C             the transformed input matrix U' * B.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the output matrix C.
-C             On exit, the leading P-by-N part of this array contains
-C             the transformed output matrix C * U.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,P).
-C
-C     U       (output) DOUBLE PRECISION array, dimension (LDU,N)
-C             The leading N-by-N part of this array contains the
-C             orthogonal transformation matrix used to reduce A to the
-C             real Schur form. The columns of U are the Schur vectors of
-C             matrix A.
-C
-C     LDU     INTEGER
-C             The leading dimension of array U.  LDU >= max(1,N).
-C
-C     WR, WI  (output) DOUBLE PRECISION arrays, dimension (N)
-C             WR and WI contain the real and imaginary parts,
-C             respectively, of the computed eigenvalues of A. The
-C             eigenvalues will be in the same order that they appear on
-C             the diagonal of the output real Schur form of A. Complex
-C             conjugate pairs of eigenvalues will appear consecutively
-C             with the eigenvalue having the positive imaginary part
-C             first.
-C
-C     Workspace
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The dimension of working array DWORK.  LWORK >= 3*N.
-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             > 0:  if INFO = i, the QR algorithm failed to compute
-C                   all the eigenvalues; elements i+1:N of WR and WI
-C                   contain those eigenvalues which have converged;
-C                   U contains the matrix which reduces A to its
-C                   partially converged Schur form.
-C
-C     METHOD
-C
-C     Matrix A is reduced to a real Schur form using an orthogonal
-C     similarity transformation A <- U'*A*U. Then, the transformation
-C     is applied to the matrices B and C: B <-- U'*B and C <-- C*U.
-C
-C     NUMERICAL ASPECTS
-C                                     3
-C     The algorithm requires about 10N  floating point operations.
-C
-C     CONTRIBUTOR
-C
-C     A. Varga, German Aerospace Center,
-C     DLR Oberpfaffenhofen, March 1998.
-C     Based on the RASP routine SRSFDC.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Orthogonal transformation, real Schur form, similarity
-C     transformation.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION ZERO, ONE
-      PARAMETER        ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER          INFO, LDA, LDB, LDC, LDU, LDWORK, M, N, P
-C     .. Array Arguments ..
-      DOUBLE PRECISION A(LDA,*), B(LDB,*), C(LDC,*), DWORK(*), U(LDU,*),
-     $                 WI(*), WR(*)
-C     .. Local Scalars ..
-      INTEGER          I, LDWP, SDIM
-      DOUBLE PRECISION WRKOPT
-C     .. Local Arrays ..
-      LOGICAL          BWORK( 1 )
-C     .. External Functions ..
-      LOGICAL          LSAME, SELECT
-      EXTERNAL         LSAME, SELECT
-C     .. External Subroutines ..
-      EXTERNAL         DCOPY, DGEES, DGEMM, DGEMV, DLACPY, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC        DBLE, MAX
-C
-C     .. Executable Statements ..
-C
-      INFO = 0
-C
-C     Check input parameters.
-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( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -5
-      ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-         INFO = -7
-      ELSE IF( LDC.LT.MAX( 1, P ) ) THEN
-         INFO = -9
-      ELSE IF( LDU.LT.MAX( 1, N ) ) THEN
-         INFO = -11
-      ELSE IF( LDWORK.LT.3*N ) THEN
-         INFO = -15
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'TB01WD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF( N.EQ.0 )
-     $   RETURN
-C
-C     Reduce A to real Schur form using an orthogonal similarity
-C     transformation A <- U'*A*U, accumulate the transformation in U
-C     and compute the eigenvalues of A in (WR,WI).
-C
-C     Workspace:  need   3*N;
-C                 prefer larger.
-C
-      CALL DGEES( 'Vectors', 'Not ordered', SELECT, N, A, LDA, SDIM,
-     $            WR, WI, U, LDU, DWORK, LDWORK, BWORK, INFO )
-      WRKOPT = DWORK( 1 )
-      IF( INFO.NE.0 )
-     $    RETURN
-C
-C     Apply the transformation: B <-- U'*B.
-C
-      IF( LDWORK.LT.N*M ) THEN
-C
-C        Not enough working space for using DGEMM.
-C
-         DO 10 I = 1, M
-            CALL DCOPY( N, B(1,I), 1, DWORK, 1 )
-            CALL DGEMV( 'Transpose', N, N, ONE, U, LDU, DWORK, 1, ZERO,
-     $                  B(1,I), 1 )
-   10    CONTINUE
-C
-      ELSE
-         CALL DLACPY( 'Full', N, M, B, LDB, DWORK, N )
-         CALL DGEMM( 'Transpose', 'No transpose', N, M, N, ONE, U, LDU,
-     $               DWORK, N, ZERO, B, LDB )
-         WRKOPT = MAX( WRKOPT, DBLE( N*M ) )
-      END IF
-C
-C     Apply the transformation: C <-- C*U.
-C
-      IF( LDWORK.LT.N*P ) THEN
-C
-C        Not enough working space for using DGEMM.
-C
-         DO 20 I = 1, P
-            CALL DCOPY( N, C(I,1), LDC, DWORK, 1 )
-            CALL DGEMV( 'Transpose', N, N, ONE, U, LDU, DWORK, 1, ZERO,
-     $                  C(I,1), LDC )
-   20    CONTINUE
-C
-      ELSE
-         LDWP = MAX( 1, P )
-         CALL DLACPY( 'Full', P, N, C, LDC, DWORK, LDWP )
-         CALL DGEMM( 'No transpose', 'No transpose', P, N, N, ONE,
-     $               DWORK, LDWP, U, LDU, ZERO, C, LDC )
-         WRKOPT = MAX( WRKOPT, DBLE( N*P ) )
-      END IF
-C
-      DWORK( 1 ) = WRKOPT
-C
-      RETURN
-C *** Last line of TB01WD ***
-      END
--- a/extra/control-devel/src/TB01XD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,284 +0,0 @@
-      SUBROUTINE TB01XD( JOBD, N, M, P, KL, KU, A, LDA, B, LDB, C, LDC,
-     $                   D, LDD, 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     <http://www.gnu.org/licenses/>.
-C
-C     PURPOSE
-C
-C     To apply a special transformation to a system given as a triple
-C     (A,B,C),
-C
-C        A <-- P * A' * P,  B <-- P * C',  C <-- B' * P,
-C
-C     where P is a matrix with 1 on the secondary diagonal, and with 0
-C     in the other entries. Matrix A can be specified as a band matrix.
-C     Optionally, matrix D of the system can be transposed. This
-C     transformation is actually a special similarity transformation of
-C     the dual system.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     JOBD    CHARACTER*1
-C             Specifies whether or not a non-zero matrix D appears in
-C             the given state space model:
-C             = 'D':  D is present;
-C             = 'Z':  D is assumed a zero matrix.
-C
-C     Input/Output Parameters
-C
-C     N       (input) INTEGER
-C             The order of the matrix A, the number of rows of matrix B
-C             and the number of columns of matrix C.
-C             N represents the dimension of the state vector.  N >= 0.
-C
-C     M       (input) INTEGER.
-C             The number of columns of matrix B.
-C             M represents the dimension of input vector.  M >= 0.
-C
-C     P       (input) INTEGER.
-C             The number of rows of matrix C.
-C             P represents the dimension of output vector.  P >= 0.
-C
-C     KL      (input) INTEGER
-C             The number of subdiagonals of A to be transformed.
-C             MAX( 0, N-1 ) >= KL >= 0.
-C
-C     KU      (input) INTEGER
-C             The number of superdiagonals of A to be transformed.
-C             MAX( 0, N-1 ) >= KU >= 0.
-C
-C     A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
-C             On entry, the leading N-by-N part of this array must
-C             contain the system state matrix A.
-C             On exit, the leading N-by-N part of this array contains
-C             the transformed (pertransposed) matrix P*A'*P.
-C
-C     LDA     INTEGER
-C             The leading dimension of the array A.  LDA >= MAX(1,N).
-C
-C     B       (input/output) DOUBLE PRECISION array, dimension
-C             (LDB,MAX(M,P))
-C             On entry, the leading N-by-M part of this array must
-C             contain the original input/state matrix B.
-C             On exit, the leading N-by-P part of this array contains
-C             the dual input/state matrix P*C'.
-C
-C     LDB     INTEGER
-C             The leading dimension of the array B.
-C             LDB >= MAX(1,N) if M > 0 or  P > 0.
-C             LDB >= 1        if M = 0 and P = 0.
-C
-C     C       (input/output) DOUBLE PRECISION array, dimension (LDC,N)
-C             On entry, the leading P-by-N part of this array must
-C             contain the original state/output matrix C.
-C             On exit, the leading M-by-N part of this array contains
-C             the dual state/output matrix B'*P.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.
-C             LDC >= MAX(1,M,P) if N > 0.
-C             LDC >= 1          if N = 0.
-C
-C     D       (input/output) DOUBLE PRECISION array, dimension
-C             (LDD,MAX(M,P))
-C             On entry, if JOBD = 'D', the leading P-by-M part of this
-C             array must contain the original direct transmission
-C             matrix D.
-C             On exit, if JOBD = 'D', the leading M-by-P part of this
-C             array contains the transposed direct transmission matrix
-C             D'. The array D is not referenced if JOBD = 'Z'.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.
-C             LDD >= MAX(1,M,P) if JOBD = 'D'.
-C             LDD >= 1          if JOBD = 'Z'.
-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     METHOD
-C
-C     The rows and/or columns of the matrices of the triplet (A,B,C)
-C     and, optionally, of the matrix D are swapped in a special way.
-C
-C     NUMERICAL ASPECTS
-C
-C     None.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, Feb. 1998.
-C     Partly based on routine DMPTR (A. Varga, German Aerospace
-C     Research Establishment, DLR, Aug. 1992).
-C
-C
-C     REVISIONS
-C
-C     07-31-1998, 04-25-1999, A. Varga.
-C     03-16-2004, V. Sima.
-C
-C     KEYWORDS
-C
-C     Matrix algebra, matrix operations, similarity transformation.
-C
-C  *********************************************************************
-C
-C     ..
-C     .. Scalar Arguments ..
-      CHARACTER          JOBD
-      INTEGER            INFO, KL, KU, LDA, LDB, LDC, LDD, M, N, P
-C     ..
-C     .. Array Arguments ..
-      DOUBLE PRECISION   A( LDA, * ), B( LDB, * ), C( LDC, * ),
-     $                   D( LDD, * )
-C     ..
-C     .. Local Scalars ..
-      LOGICAL            LJOBD
-      INTEGER            J, J1, LDA1, MAXMP, MINMP, NM1
-C     ..
-C     .. External functions ..
-      LOGICAL            LSAME
-      EXTERNAL           LSAME
-C     ..
-C     .. External Subroutines ..
-      EXTERNAL           DCOPY, DSWAP, XERBLA
-C     ..
-C     .. Intrinsic Functions ..
-      INTRINSIC          MAX, MIN
-C     ..
-C     .. Executable Statements ..
-C
-C     Test the scalar input arguments.
-C
-      INFO  = 0
-      LJOBD = LSAME( JOBD, 'D' )
-      MAXMP = MAX( M, P )
-      MINMP = MIN( M, P )
-      NM1   = N - 1
-C
-      IF( .NOT.LJOBD .AND. .NOT.LSAME( JOBD, 'Z' )  ) THEN
-         INFO = -1
-      ELSE IF( N.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -4
-      ELSE IF( KL.LT.0 .OR. KL.GT.MAX( 0, NM1 ) ) THEN
-         INFO = -5
-      ELSE IF( KU.LT.0 .OR. KU.GT.MAX( 0, NM1 ) ) THEN
-         INFO = -6
-      ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
-         INFO = -8
-      ELSE IF( ( MAXMP.GT.0 .AND. LDB.LT.MAX( 1, N ) ) .OR.
-     $         ( MINMP.EQ.0 .AND. LDB.LT.1 ) ) THEN
-         INFO = -10
-      ELSE IF( LDC.LT.1 .OR. ( N.GT.0 .AND. LDC.LT.MAXMP ) ) THEN
-         INFO = -12
-      ELSE IF( LDD.LT.1 .OR. ( LJOBD  .AND. LDD.LT.MAXMP ) ) THEN
-         INFO = -14
-      END IF
-C
-      IF( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'TB01XD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( LJOBD ) THEN
-C
-C        Replace D by D', if non-scalar.
-C
-         DO 5 J = 1, MAXMP
-            IF ( J.LT.MINMP ) THEN
-               CALL DSWAP( MINMP-J, D(J+1,J), 1, D(J,J+1), LDD )
-            ELSE IF ( J.GT.P ) THEN
-               CALL DCOPY( P, D(1,J), 1, D(J,1), LDD )
-            ELSE IF ( J.GT.M ) THEN
-               CALL DCOPY( M, D(J,1), LDD, D(1,J), 1 )
-            END IF
-    5    CONTINUE
-C
-      END IF
-C
-      IF( N.EQ.0 )
-     $   RETURN
-C
-C     Replace matrix A by P*A'*P.
-C
-      IF ( KL.EQ.NM1 .AND. KU.EQ.NM1 ) THEN
-C
-C        Full matrix A.
-C
-         DO 10 J = 1, NM1
-            CALL DSWAP( N-J, A( 1, J ), 1, A( N-J+1, J+1 ), -LDA )
-   10    CONTINUE
-C
-      ELSE
-C
-C        Band matrix A.
-C
-         LDA1 = LDA + 1
-C
-C        Pertranspose the KL subdiagonals.
-C
-         DO 20 J = 1, MIN( KL, N-2 )
-            J1 = ( N - J )/2
-            CALL DSWAP( J1, A(J+1,1), LDA1, A(N-J1+1,N-J1+1-J), -LDA1 )
-   20    CONTINUE
-C
-C        Pertranspose the KU superdiagonals.
-C
-         DO 30 J = 1, MIN( KU, N-2 )
-            J1 = ( N - J )/2
-            CALL DSWAP( J1, A(1,J+1), LDA1, A(N-J1+1-J,N-J1+1), -LDA1 )
-   30    CONTINUE
-C
-C        Pertranspose the diagonal.
-C
-         J1 = N/2
-         CALL DSWAP( J1, A(1,1), LDA1, A(N-J1+1,N-J1+1), -LDA1 )
-C
-      END IF
-C
-C     Replace matrix B by P*C' and matrix C by B'*P.
-C
-      DO 40 J = 1, MAXMP
-         IF ( J.LE.MINMP ) THEN
-            CALL DSWAP( N, B(1,J), 1, C(J,1), -LDC )
-         ELSE IF ( J.GT.P ) THEN
-            CALL DCOPY( N, B(1,J), 1, C(J,1), -LDC )
-         ELSE
-            CALL DCOPY( N, C(J,1), -LDC, B(1,J), 1 )
-         END IF
-   40 CONTINUE
-C
-      RETURN
-C *** Last line of TB01XD ***
-      END
--- a/extra/control-devel/src/TD03AY.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-      SUBROUTINE TD03AY( MWORK, PWORK, INDEX, DCOEFF, LDDCOE, UCOEFF,
-     $                   LDUCO1, LDUCO2, N, A, LDA, B, LDB, C, LDC, D,
-     $                   LDD, 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     Calculates a state-space representation for a (PWORK x MWORK)
-C     transfer matrix given in the form of polynomial row vectors over
-C     common denominators (not necessarily lcd's).  Such a description
-C     is simply the polynomial matrix representation
-C
-C          T(s) = inv(D(s)) * U(s),
-C
-C     where D(s) is diagonal with (I,I)-th element D:I(s) of degree
-C     INDEX(I); applying Wolovich's Observable Structure Theorem to
-C     this left matrix fraction then yields an equivalent state-space
-C     representation in observable companion form, of order
-C     N = sum(INDEX(I)).  As D(s) is diagonal, the PWORK ordered
-C     'non-trivial' columns of C and A are very simply calculated, these
-C     submatrices being diagonal and (INDEX(I) x 1) - block diagonal,
-C     respectively: finding B and D is also somewhat simpler than for
-C     general P(s) as dealt with in TC04AD. Finally, the state-space
-C     representation obtained here is not necessarily controllable
-C     (as D(s) and U(s) are not necessarily relatively left prime), but
-C     it is theoretically completely observable: however, its
-C     observability matrix may be poorly conditioned, so it is safer
-C     not to assume observability either.
-C
-C     REVISIONS
-C
-C     May 13, 1998.
-C
-C     KEYWORDS
-C
-C     Coprime matrix fraction, elementary polynomial operations,
-C     polynomial matrix, state-space representation, transfer matrix.
-C
-C     ******************************************************************
-C
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      INTEGER           INFO, LDA, LDB, LDC, LDD, LDDCOE, LDUCO1,
-     $                  LDUCO2, MWORK, N, PWORK
-C     .. Array Arguments ..
-      INTEGER           INDEX(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                  DCOEFF(LDDCOE,*), UCOEFF(LDUCO1,LDUCO2,*)
-C     .. Local Scalars ..
-      INTEGER           I, IA, IBIAS, INDCUR, JA, JMAX1, K
-      DOUBLE PRECISION  ABSDIA, ABSDMX, BIGNUM, DIAG, SMLNUM, UMAX1,
-     $                  TEMP
-C     .. External Functions ..
-      INTEGER           IDAMAX
-      DOUBLE PRECISION  DLAMCH
-      EXTERNAL          DLAMCH, IDAMAX
-C     .. External Subroutines ..
-      EXTERNAL          DAXPY, DCOPY, DLASET, DSCAL
-C     .. Intrinsic Functions ..
-      INTRINSIC         ABS
-C     .. Executable Statements ..
-C
-      INFO = 0
-C
-C     Initialize A and C to be zero, apart from 1's on the subdiagonal
-C     of A.
-C
-      CALL DLASET( 'Upper', N, N, ZERO, ZERO, A, LDA )
-      IF ( N.GT.1 ) CALL DLASET( 'Lower', N-1, N-1, ZERO, ONE, A(2,1),
-     $                           LDA )
-C
-      CALL DLASET( 'Full', PWORK, N, ZERO, ZERO, C, LDC )
-C
-C     Calculate B and D, as well as 'non-trivial' elements of A and C.
-C     Check if any leading coefficient of D(s) nearly zero: if so, exit.
-C     Caution is taken to avoid overflow.
-C
-      SMLNUM = DLAMCH( 'Safe minimum' ) / DLAMCH( 'Precision' )
-      BIGNUM = ONE / SMLNUM
-C
-      IBIAS = 2
-      JA = 0
-C
-      DO 20 I = 1, PWORK
-         ABSDIA = ABS( DCOEFF(I,1) )
-         JMAX1  = IDAMAX( MWORK, UCOEFF(I,1,1), LDUCO1 )
-         UMAX1  = ABS( UCOEFF(I,JMAX1,1) )
-         IF ( ( ABSDIA.LT.SMLNUM ) .OR.
-     $        ( ABSDIA.LT.ONE .AND. UMAX1.GT.ABSDIA*BIGNUM ) ) THEN
-C
-C           Error return.
-C
-            INFO = I
-            RETURN
-         END IF
-         DIAG   = ONE/DCOEFF(I,1)
-         INDCUR = INDEX(I)
-         IF ( INDCUR.NE.0 ) THEN
-            IBIAS = IBIAS + INDCUR
-            JA = JA + INDCUR
-            IF ( INDCUR.GE.1 ) THEN
-               JMAX1  = IDAMAX( INDCUR, DCOEFF(I,2), LDDCOE )
-               ABSDMX = ABS( DCOEFF(I,JMAX1) )
-               IF ( ABSDIA.GE.ONE ) THEN
-                  IF ( UMAX1.GT.ONE ) THEN
-                     IF ( ( ABSDMX/ABSDIA ).GT.( BIGNUM/UMAX1 ) ) THEN
-C
-C                       Error return.
-C
-                        INFO = I
-                        RETURN
-                     END IF
-                  END IF
-               ELSE
-                  IF ( UMAX1.GT.ONE ) THEN
-                     IF ( ABSDMX.GT.( BIGNUM*ABSDIA )/UMAX1 ) THEN
-C
-C                       Error return.
-C
-                        INFO = I
-                        RETURN
-                     END IF
-                  END IF
-               END IF
-            END IF
-C
-C           I-th 'non-trivial' sub-vector of A given from coefficients
-C           of D:I(s), while I-th row block of B given from this and
-C           row I of U(s).
-C
-            DO 10 K = 2, INDCUR + 1
-               IA = IBIAS - K
-               TEMP = -DIAG*DCOEFF(I,K)
-               A(IA,JA) = TEMP
-C
-               CALL DCOPY( MWORK, UCOEFF(I,1,K), LDUCO1, B(IA,1), LDB )
-               CALL DAXPY( MWORK, TEMP, UCOEFF(I,1,1), LDUCO1, B(IA,1),
-     $                     LDB )
-   10       CONTINUE
-C
-            IF ( JA.LT.N ) A(JA+1,JA) = ZERO
-C
-C           Finally, I-th 'non-trivial' entry of C and row of D obtained
-C           also.
-C
-            C(I,JA) = DIAG
-         END IF
-C
-         CALL DCOPY( MWORK, UCOEFF(I,1,1), LDUCO1, D(I,1), LDD )
-         CALL DSCAL( MWORK, DIAG, D(I,1), LDD )
-   20 CONTINUE
-C
-      RETURN
-C *** Last line of TD03AY ***
-      END
--- a/extra/control-devel/src/TD04AD.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,425 +0,0 @@
-      SUBROUTINE TD04AD( ROWCOL, M, P, INDEX, DCOEFF, LDDCOE, UCOEFF,
-     $                   LDUCO1, LDUCO2, NR, A, LDA, B, LDB, C, LDC, D,
-     $                   LDD, 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 find a minimal state-space representation (A,B,C,D) for a
-C     proper transfer matrix T(s) given as either row or column
-C     polynomial vectors over denominator polynomials, possibly with
-C     uncancelled common terms.
-C
-C     ARGUMENTS
-C
-C     Mode Parameters
-C
-C     ROWCOL  CHARACTER*1
-C             Indicates whether the transfer matrix T(s) is given as
-C             rows or columns over common denominators as follows:
-C             = 'R':  T(s) is given as rows over common denominators;
-C             = 'C':  T(s) is given as columns over common denominators.
-C
-C     Input/Output Parameters
-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     INDEX   (input) INTEGER array, dimension (porm), where porm = P,
-C             if ROWCOL = 'R', and porm = M, if ROWCOL = 'C'.
-C             This array must contain the degrees of the denominator
-C             polynomials in D(s).
-C
-C     DCOEFF  (input) DOUBLE PRECISION array, dimension (LDDCOE,kdcoef),
-C             where kdcoef = MAX(INDEX(I)) + 1.
-C             The leading porm-by-kdcoef part of this array must contain
-C             the coefficients of each denominator polynomial.
-C             DCOEFF(I,K) is the coefficient in s**(INDEX(I)-K+1) of the
-C             I-th denominator polynomial in D(s), where
-C             K = 1,2,...,kdcoef.
-C
-C     LDDCOE  INTEGER
-C             The leading dimension of array DCOEFF.
-C             LDDCOE >= MAX(1,P) if ROWCOL = 'R';
-C             LDDCOE >= MAX(1,M) if ROWCOL = 'C'.
-C
-C     UCOEFF  (input) DOUBLE PRECISION array, dimension
-C             (LDUCO1,LDUCO2,kdcoef)
-C             The leading P-by-M-by-kdcoef part of this array must
-C             contain the numerator matrix U(s); if ROWCOL = 'C', this
-C             array is modified internally but restored on exit, and the
-C             remainder of the leading MAX(M,P)-by-MAX(M,P)-by-kdcoef
-C             part is used as internal workspace.
-C             UCOEFF(I,J,K) is the coefficient in s**(INDEX(iorj)-K+1)
-C             of polynomial (I,J) of U(s), where K = 1,2,...,kdcoef;
-C             if ROWCOL = 'R' then iorj = I, otherwise iorj = J.
-C             Thus for ROWCOL = 'R', U(s) =
-C             diag(s**INDEX(I))*(UCOEFF(.,.,1)+UCOEFF(.,.,2)/s+...).
-C
-C     LDUCO1  INTEGER
-C             The leading dimension of array UCOEFF.
-C             LDUCO1 >= MAX(1,P)   if ROWCOL = 'R';
-C             LDUCO1 >= MAX(1,M,P) if ROWCOL = 'C'.
-C
-C     LDUCO2  INTEGER
-C             The second dimension of array UCOEFF.
-C             LDUCO2 >= MAX(1,M)   if ROWCOL = 'R';
-C             LDUCO2 >= MAX(1,M,P) if ROWCOL = 'C'.
-C
-C     NR      (output) INTEGER
-C             The order of the resulting minimal realization, i.e. the
-C             order of the state dynamics matrix A.
-C
-C     A       (output) DOUBLE PRECISION array, dimension (LDA,N),
-C                       porm
-C             where N = SUM INDEX(I).
-C                       I=1
-C             The leading NR-by-NR part of this array contains the upper
-C             block Hessenberg state dynamics matrix A of a minimal
-C             realization.
-C
-C     LDA     INTEGER
-C             The leading dimension of array A.  LDA >= MAX(1,N).
-C
-C     B       (output) DOUBLE PRECISION array, dimension (LDB,MAX(M,P))
-C             The leading NR-by-M part of this array contains the
-C             input/state matrix B of a minimal realization; the
-C             remainder of the leading N-by-MAX(M,P) part is used as
-C             internal workspace.
-C
-C     LDB     INTEGER
-C             The leading dimension of array B.  LDB >= MAX(1,N).
-C
-C     C       (output) DOUBLE PRECISION array, dimension (LDC,N)
-C             The leading P-by-NR part of this array contains the
-C             state/output matrix C of a minimal realization; the
-C             remainder of the leading MAX(M,P)-by-N part is used as
-C             internal workspace.
-C
-C     LDC     INTEGER
-C             The leading dimension of array C.  LDC >= MAX(1,M,P).
-C
-C     D       (output) DOUBLE PRECISION array, dimension (LDD,M),
-C             if ROWCOL = 'R', and (LDD,MAX(M,P)) if ROWCOL = 'C'.
-C             The leading P-by-M part of this array contains the direct
-C             transmission matrix D; if ROWCOL = 'C', the remainder of
-C             the leading MAX(M,P)-by-MAX(M,P) part is used as internal
-C             workspace.
-C
-C     LDD     INTEGER
-C             The leading dimension of array D.
-C             LDD >= MAX(1,P)   if ROWCOL = 'R';
-C             LDD >= MAX(1,M,P) if ROWCOL = 'C'.
-C
-C     Tolerances
-C
-C     TOL     DOUBLE PRECISION
-C             The tolerance to be used in rank determination when
-C             transforming (A, B, C). If the user sets TOL > 0, then
-C             the given value of TOL is used as a lower bound for the
-C             reciprocal condition number (see the description of the
-C             argument RCOND in the SLICOT routine MB03OD);  a
-C             (sub)matrix whose estimated condition number is less than
-C             1/TOL is considered to be of full rank.  If the user sets
-C             TOL <= 0, then an implicitly computed, default tolerance
-C             (determined by the SLICOT routine TB01UD) is used instead.
-C
-C     Workspace
-C
-C     IWORK   INTEGER array, dimension (N+MAX(M,P))
-C             On exit, if INFO = 0, the first nonzero elements of
-C             IWORK(1:N) return the orders of the diagonal blocks of A.
-C
-C     DWORK   DOUBLE PRECISION array, dimension (LDWORK)
-C             On exit, if INFO = 0, DWORK(1) returns the optimal value
-C             of LDWORK.
-C
-C     LDWORK  INTEGER
-C             The length of the array DWORK.
-C             LDWORK >= MAX(1, N + MAX(N, 3*M, 3*P)).
-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             > 0:  if INFO = i, then i is the first integer for which
-C                   ABS( DCOEFF(I,1) ) is so small that the calculations
-C                   would overflow (see SLICOT Library routine TD03AY);
-C                   that is, the leading coefficient of a polynomial is
-C                   nearly zero; no state-space representation is
-C                   calculated.
-C
-C     METHOD
-C
-C     The method for transfer matrices factorized by rows will be
-C     described here: T(s) factorized by columns is dealt with by
-C     operating on the dual T'(s). This description for T(s) is
-C     actually the left polynomial matrix representation
-C
-C          T(s) = inv(D(s))*U(s),
-C
-C     where D(s) is diagonal with its (I,I)-th polynomial element of
-C     degree INDEX(I). The first step is to check whether the leading
-C     coefficient of any polynomial element of D(s) is approximately
-C     zero; if so the routine returns with INFO > 0. Otherwise,
-C     Wolovich's Observable Structure Theorem is used to construct a
-C     state-space representation in observable companion form which
-C     is equivalent to the above polynomial matrix representation.
-C     The method is particularly easy here due to the diagonal form
-C     of D(s). This state-space representation is not necessarily
-C     controllable (as D(s) and U(s) are not necessarily relatively
-C     left prime), but it is in theory completely observable; however,
-C     its observability matrix may be poorly conditioned, so it is
-C     treated as a general state-space representation and SLICOT
-C     Library routine TB01PD is then called to separate out a minimal
-C     realization from this general state-space representation by means
-C     of orthogonal similarity transformations.
-C
-C     REFERENCES
-C
-C     [1] Patel, R.V.
-C         Computation of Minimal-Order State-Space Realizations and
-C         Observability Indices using Orthogonal Transformations.
-C         Int. J. Control, 33, pp. 227-246, 1981.
-C
-C     [2] Wolovich, W.A.
-C         Linear Multivariable Systems, (Theorem 4.3.3).
-C         Springer-Verlag, 1974.
-C
-C     NUMERICAL ASPECTS
-C                               3
-C     The algorithm requires 0(N ) operations.
-C
-C     CONTRIBUTOR
-C
-C     V. Sima, Katholieke Univ. Leuven, Belgium, March 1998.
-C     Supersedes Release 3.0 routine TD01OD.
-C
-C     REVISIONS
-C
-C     -
-C
-C     KEYWORDS
-C
-C     Controllability, elementary polynomial operations, minimal
-C     realization, polynomial matrix, state-space representation,
-C     transfer matrix.
-C
-C     ******************************************************************
-C
-C     .. Parameters ..
-      DOUBLE PRECISION  ZERO, ONE
-      PARAMETER         ( ZERO = 0.0D0, ONE = 1.0D0 )
-C     .. Scalar Arguments ..
-      CHARACTER         ROWCOL
-      INTEGER           INFO, LDA, LDB, LDC, LDD, LDDCOE, LDUCO1,
-     $                  LDUCO2, LDWORK, M, NR, P
-      DOUBLE PRECISION  TOL
-C     .. Array Arguments ..
-      INTEGER           INDEX(*), IWORK(*)
-      DOUBLE PRECISION  A(LDA,*), B(LDB,*), C(LDC,*), D(LDD,*),
-     $                  DCOEFF(LDDCOE,*), DWORK(*),
-     $                  UCOEFF(LDUCO1,LDUCO2,*)
-C     .. Local Scalars ..
-      LOGICAL           LROCOC, LROCOR
-      INTEGER           I, J, JSTOP, K, KDCOEF, MPLIM, MWORK, N, PWORK
-C     .. External Functions ..
-      LOGICAL           LSAME
-      EXTERNAL          LSAME
-C     .. External Subroutines ..
-      EXTERNAL          DLASET, DSWAP, TB01PD, TB01XD, TD03AY, XERBLA
-C     .. Intrinsic Functions ..
-      INTRINSIC         MAX
-C     .. Executable Statements ..
-C
-      INFO = 0
-      LROCOR = LSAME( ROWCOL, 'R' )
-      LROCOC = LSAME( ROWCOL, 'C' )
-      MPLIM = MAX( 1, M, P )
-C
-C     Test the input scalar arguments.
-C
-      IF( .NOT.LROCOR .AND. .NOT.LROCOC ) THEN
-         INFO = -1
-      ELSE IF( M.LT.0 ) THEN
-         INFO = -2
-      ELSE IF( P.LT.0 ) THEN
-         INFO = -3
-      ELSE IF( ( LROCOR .AND. LDDCOE.LT.MAX( 1, P ) ) .OR.
-     $         ( LROCOC .AND. LDDCOE.LT.MAX( 1, M ) ) ) THEN
-         INFO = -6
-      ELSE IF( ( LROCOR .AND. LDUCO1.LT.MAX( 1, P ) ) .OR.
-     $         ( LROCOC .AND. LDUCO1.LT.MPLIM ) ) THEN
-         INFO = -8
-      ELSE IF( ( LROCOR .AND. LDUCO2.LT.MAX( 1, M ) ) .OR.
-     $         ( LROCOC .AND. LDUCO2.LT.MPLIM ) ) THEN
-         INFO = -9
-      END IF
-C
-      N = 0
-      IF ( INFO.EQ.0 ) THEN
-         IF ( LROCOR ) THEN
-C
-C           Initialization for T(s) given as rows over common
-C           denominators.
-C
-            PWORK = P
-            MWORK = M
-         ELSE
-C
-C           Initialization for T(s) given as columns over common
-C           denominators.
-C
-            PWORK = M
-            MWORK = P
-         END IF
-C
-C        Calculate N, the order of the resulting state-space
-C        representation.
-C
-         KDCOEF = 0
-C
-         DO 10 I = 1, PWORK
-            KDCOEF = MAX( KDCOEF, INDEX(I) )
-            N = N + INDEX(I)
-   10    CONTINUE
-C
-         KDCOEF = KDCOEF + 1
-C
-         IF( LDA.LT.MAX( 1, N ) ) THEN
-            INFO = -12
-         ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
-            INFO = -14
-         ELSE IF( LDC.LT.MPLIM ) THEN
-            INFO = -16
-         ELSE IF( ( LROCOR .AND. LDD.LT.MAX( 1, P ) ) .OR.
-     $         ( LROCOC .AND. LDD.LT.MPLIM ) ) THEN
-            INFO = -18
-         ELSE IF( LDWORK.LT.MAX( 1, N + MAX( N, 3*M, 3*P ) ) ) THEN
-            INFO = -22
-         END IF
-      END IF
-C
-      IF ( INFO.NE.0 ) THEN
-C
-C        Error return.
-C
-         CALL XERBLA( 'TD04AD', -INFO )
-         RETURN
-      END IF
-C
-C     Quick return if possible.
-C
-      IF ( MAX( N, M, P ).EQ.0 ) THEN
-         NR  = 0
-         DWORK(1) = ONE
-         RETURN
-      END IF
-C
-      IF ( LROCOC ) THEN
-C
-C        Initialize the remainder of the leading
-C        MPLIM-by-MPLIM-by-KDCOEF part of U(s) to zero.
-C
-         IF ( P.LT.M ) THEN
-C
-            DO 20 K = 1, KDCOEF
-               CALL DLASET( 'Full', M-P, MPLIM, ZERO, ZERO,
-     $                      UCOEFF(P+1,1,K), LDUCO1 )
-   20       CONTINUE
-C
-         ELSE IF ( P.GT.M ) THEN
-C
-            DO 30 K = 1, KDCOEF
-               CALL DLASET( 'Full', MPLIM, P-M, ZERO, ZERO,
-     $                      UCOEFF(1,M+1,K), LDUCO1 )
-   30       CONTINUE
-C
-         END IF
-C
-         IF ( MPLIM.NE.1 ) THEN
-C
-C           Non-scalar T(s) factorized by columns: transpose it (i.e.
-C           U(s)).
-C
-            JSTOP = MPLIM - 1
-C
-            DO 50 K = 1, KDCOEF
-C
-               DO 40 J = 1, JSTOP
-                  CALL DSWAP( MPLIM-J, UCOEFF(J+1,J,K), 1,
-     $                        UCOEFF(J,J+1,K), LDUCO1 )
-   40          CONTINUE
-C
-   50       CONTINUE
-C
-         END IF
-      END IF
-C
-C     Construct non-minimal state-space representation (by Wolovich's
-C     Structure Theorem) which has transfer matrix T(s) or T'(s) as
-C     appropriate ...
-C
-      CALL TD03AY( MWORK, PWORK, INDEX, DCOEFF, LDDCOE, UCOEFF, LDUCO1,
-     $             LDUCO2, N, A, LDA, B, LDB, C, LDC, D, LDD, INFO )
-      IF ( INFO.GT.0 )
-     $   RETURN
-C
-C     and then separate out a minimal realization from this.
-C
-C     Workspace: need  N + MAX(N, 3*MWORK, 3*PWORK).
-C
-      CALL TB01PD( 'Minimal', 'Scale', N, MWORK, PWORK, A, LDA, B, LDB,
-     $             C, LDC, NR, TOL, IWORK, DWORK, LDWORK, INFO )
-C
-      IF ( LROCOC ) THEN
-C
-C        If T(s) originally factorized by columns, find dual of minimal
-C        state-space representation, and reorder the rows and columns
-C        to get an upper block Hessenberg state dynamics matrix.
-C
-         K = IWORK(1)+IWORK(2)-1
-         CALL TB01XD( 'D', NR, MWORK, PWORK, K, NR-1, A, LDA, B, LDB,
-     $                C, LDC, D, LDD, INFO )
-         IF ( MPLIM.NE.1 ) THEN
-C
-C           Also, retranspose U(s) if this is non-scalar.
-C
-            DO 70 K = 1, KDCOEF
-C
-               DO 60 J = 1, JSTOP
-                  CALL DSWAP( MPLIM-J, UCOEFF(J+1,J,K), 1,
-     $                        UCOEFF(J,J+1,K), LDUCO1 )
-   60          CONTINUE
-C
-   70       CONTINUE
-C
-         END IF
-      END IF
-C
-      RETURN
-C *** Last line of TD04AD ***
-      END
--- a/extra/control-devel/src/delctg.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-      LOGICAL FUNCTION  DELCTG( PAR1, PAR2, PAR3 )
-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     <http://www.gnu.org/licenses/>.
-C
-C     Void logical function for DGGES.
-C
-      DOUBLE PRECISION  PAR1, PAR2, PAR3
-C
-      DELCTG = .TRUE.
-      RETURN
-      END
--- a/extra/control-devel/src/select.f	Wed Feb 22 15:13:45 2012 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-      LOGICAL FUNCTION  SELECT( PAR1, PAR2 )
-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     Void logical function for DGEES.
-C
-      DOUBLE PRECISION  PAR1, PAR2
-C
-      SELECT = .TRUE.
-      RETURN
-      END
Binary file extra/control-devel/src/slicot.tar.gz has changed