dynare/mex/sources/libslicot/IB01AD.f

687 lines
29 KiB
Fortran

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-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 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